import os
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'

import sys
from PyQt6.QtWidgets import (QApplication, QWidget, QMainWindow, QPushButton, QVBoxLayout, QHBoxLayout, QLabel, 
                           QLineEdit, QFrame, QSizePolicy, QStackedWidget, QScrollArea, QFileDialog, QMessageBox,
                           QDateEdit, QComboBox, QStyle, QStyleFactory, QTableWidget, QTableWidgetItem, QHeaderView,
                           QSpinBox, QProgressBar, QTextEdit, QDialog, QDialogButtonBox, QTextBrowser)
from PyQt6.QtCore import Qt, QDate, QTimer, QEvent
from PyQt6.QtGui import QIcon, QPixmap, QTextDocument
import time
from window_state import manager
from Mode.Pca import PCAWidget
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qtagg import NavigationToolbar2QT as NavigationToolbar
import numpy as np
import torch
import torch.nn as nn
from sklearn.preprocessing import StandardScaler

# 现代配色方案
DEEP_SPACE_BLUE = "#f0f0f0"  # 背景色
NEON_BLUE = "#1890ff"        # 主题蓝
ELECTRIC_PURPLE = "#722ed1"  # 紫色
LIGHT_GRAY = "#333333"      # 文字颜色

# 定义较大按钮（用于功能按钮）
class ModernButton(QPushButton):
    def __init__(self, text="", parent=None):
        super().__init__(text, parent)
        self.setFixedHeight(60)      # 设置固定高度
        self.setMinimumWidth(150)     # 设置最小宽度
        self.setCursor(Qt.CursorShape.PointingHandCursor)  # 鼠标悬停时显示手型
        self.setStyleSheet("""
            QPushButton {
                background-color: #e6f7ff;
                color: #333333;
                border: 1px solid #91d5ff;
                border-radius: 8px;
                padding: 10px 25px;
                font-size: 16px;
            }
            QPushButton:hover {
                background-color: white;
                border-color: #1890ff;
                color: #1890ff;
            }
            QPushButton:pressed {
                background-color: #40a9ff;
                color: white;
                border-color: #1890ff;
            }
            QPushButton:disabled {
                background-color: #f5f5f5;
                color: #bfbfbf;
                border: 1px solid #d9d9d9;
            }
        """)

# 定义中间面板的功能按钮
class FunctionButton(QPushButton):
    def __init__(self, text="", parent=None):
        super().__init__(text, parent)
        self.setFixedHeight(60)        # 设置固定高度
        self.setMinimumWidth(150)      # 设置最小宽度
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self.setStyleSheet("""
            QPushButton {
                background-color: #e6f7ff;
                color: #333333;
                border: 1px solid #91d5ff;
                border-radius: 8px;
                padding: 10px 25px;
                font-size: 16px;
                text-align: center;
                margin: 5px 0px;
            }
            QPushButton:hover {
                background-color: white;
                border-color: #1890ff;
                color: #1890ff;
            }
            QPushButton:pressed {
                background-color: #40a9ff;
                color: white;
                border-color: #1890ff;
            }
            QPushButton:checked {
                background-color: #40a9ff;
                color: white;
                border-color: #1890ff;
                font-weight: bold;
            }
        """)
        self.setCheckable(True)

# 定义侧边栏按钮样式
class SidebarButton(QPushButton):
    def __init__(self, text="", parent=None):
        super().__init__(text, parent)
        self.setFixedHeight(60)  # 与FunctionButton一致
        self.setMinimumWidth(150)  # 与FunctionButton一致
        self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self.setStyleSheet("""
            QPushButton {
                background-color: #e6f7ff;
                color: #333333;
                border: 1px solid #91d5ff;
                border-radius: 8px;
                padding: 10px 25px;
                font-size: 16px;
                text-align: center;
                margin: 5px 0px;
            }
            QPushButton:hover {
                background-color: white;
                border-color: #1890ff;
                color: #1890ff;
            }
            QPushButton:pressed {
                background-color: #40a9ff;
                color: white;
                border-color: #1890ff;
            }
            QPushButton:checked {
                background-color: #40a9ff;
                color: white;
                border-color: #1890ff;
                font-weight: bold;
            }
        """)
        self.setCheckable(True)

# 主窗口类
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("智能诊断系统")
        
        # 默认数据文件路径
        self.default_data_path = "data/正常数据.xlsx"
        
        # 设置窗口为无边框模式
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        
        # 初始化自动翻页定时器
        self.viz_timer = QTimer(self)
        self.viz_timer.timeout.connect(self.auto_flip_viz_page)
        self.auto_flip_enabled = False
        
        self.setStyleSheet("""
            QMainWindow {
                background-color: #f0f0f0;
            }
        """)
        
        # 设置窗口大小和位置
        screen = QApplication.primaryScreen().geometry()
        # 确保窗口大小不超过屏幕大小
        window_width = min(1200, screen.width() - 100)
        window_height = min(700, screen.height() - 100)
        self.resize(window_width, window_height)
        # 确保窗口位置在屏幕内
        self.move(
            max(0, (screen.width() - window_width) // 2),
            max(0, (screen.height() - window_height) // 2)
        )
        
        # 连接到状态管理器
        manager.state_changed.connect(self.on_state_changed)
        self.setWindowState(manager.state)
        
        # 初始化数据相关变量
        self.data_df = None
        self.file_path = None
        self.data_viz_index = None  # 初始化data_viz_index为None
        self.selected_date = QDate.currentDate()
        self.selected_workshop = "12号机"
        
        # 预加载模块
        self._preload_modules()
        
        # 创建中心部件和主布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        
        # 添加顶部控制栏
        top_control_bar = self._create_top_control_bar()
        main_layout.addWidget(top_control_bar)
        
        # 创建内容区域容器
        content_container = QWidget()
        content_layout = QHBoxLayout(content_container)
        content_layout.setContentsMargins(0, 0, 0, 0)
        content_layout.setSpacing(0)
        main_layout.addWidget(content_container)
        
        # 创建侧边栏 (左侧)
        sidebar = self._create_sidebar()
        content_layout.addWidget(sidebar)
        
        # 创建右侧区域的容器
        right_container = QWidget()
        right_layout = QVBoxLayout(right_container)
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_layout.setSpacing(0)
        content_layout.addWidget(right_container)
        
        # 创建日期和车间选择控件区域 (横跨第二栏和第三栏)
        date_workshop_widget = self._create_date_workshop_controls()
        right_layout.addWidget(date_workshop_widget)
        
        # 创建下方区域的容器
        bottom_container = QWidget()
        bottom_layout = QHBoxLayout(bottom_container)
        bottom_layout.setContentsMargins(0, 0, 0, 0)
        bottom_layout.setSpacing(0)
        right_layout.addWidget(bottom_container)
        
        # 创建中间功能区域
        self.function_panel = self._create_function_panel()
        self.function_panel.setFixedWidth(180)  # 设置固定宽度
        bottom_layout.addWidget(self.function_panel)
        
        # 创建右侧内容显示区域
        self.content_display = QStackedWidget()
        self.content_display.setStyleSheet("""
            QStackedWidget {
                background-color: #f0f0f0;
                border-left: 1px solid #e0e0e0;
            }
        """)
        
        # 添加初始空白页
        blank_page = QWidget()
        blank_page.setStyleSheet("background-color: #f0f0f0;")
        self.content_display.addWidget(blank_page)
        
        bottom_layout.addWidget(self.content_display)
        
        # 初始化功能模块实例
        self.ica_widget = None
        self.ae_widget = None
        self.spc_widget = None
        self.dl_widget = None  # 新增深度学习部件
        
        # 初始化当前选中的分析方法
        self.current_method = "home"
        
        # 自动加载默认数据
        QTimer.singleShot(300, self._auto_load_default_data)
        
        # 默认显示流程图界面 - 放在最后，确保所有UI组件都已创建
        QTimer.singleShot(500, self.show_flow_chart)
    
    def _auto_load_default_data(self):
        """自动加载默认数据文件，并根据情况控制加载数据按钮的可见性"""
        if os.path.exists(self.default_data_path):
            # 默认数据文件存在，加载数据并隐藏按钮
            self.load_data()
            if hasattr(self, 'load_data_btn'):
                self.load_data_btn.setVisible(False)
        else:
            # 默认数据文件不存在，保持按钮可见
            if hasattr(self, 'load_data_btn'):
                self.load_data_btn.setVisible(True)
    
    def _preload_modules(self):
        """预加载可能需要的模块"""
        try:
            import Mode.ica
            import aeUi
            print("模块预加载成功")
        except Exception as e:
            print(f"Module preloading failed: {str(e)}")
    
    def _create_sidebar(self):
        """创建左侧侧边栏"""
        sidebar = QFrame()
        sidebar.setFixedWidth(250)  # 增加宽度
        sidebar.setStyleSheet("""
            QFrame {
                background-color: #f0f0f0;
                border-right: 1px solid #e0e0e0;
            }
        """)
        
        sidebar_layout = QVBoxLayout(sidebar)
        sidebar_layout.setContentsMargins(10, 20, 10, 20)
        sidebar_layout.setSpacing(8)
        
        # 创建侧边栏标题
        sidebar_title = QLabel("智能诊断系统")
        sidebar_title.setStyleSheet("""
            color: #333333;
            font-size: 18px;
            font-weight: bold;
            padding: 10px;
            background-color: rgba(24, 144, 255, 0.1);
            border-radius: 4px;
        """)
        sidebar_layout.addWidget(sidebar_title)
        
        # 添加空间
        sidebar_layout.addSpacing(20)
        
        # 创建侧边栏按钮
        self.btn_home = SidebarButton("主页")
        self.btn_pca = SidebarButton("主成分分析(PCA)")
        self.btn_ica = SidebarButton("独立成分分析(ICA)")
        self.btn_ae = SidebarButton("自动编码器(AE)")
        self.btn_dl = SidebarButton("深度学习(Transformer)")
        self.btn_spc = SidebarButton("统计过程控制(SPC)")
        
        # 连接按钮事件
        self.btn_home.clicked.connect(lambda: self.change_method("home"))
        self.btn_pca.clicked.connect(lambda: self.change_method("PCA"))
        self.btn_ica.clicked.connect(lambda: self.change_method("ICA"))
        self.btn_ae.clicked.connect(lambda: self.change_method("AE"))
        self.btn_dl.clicked.connect(lambda: self.change_method("DL"))
        self.btn_spc.clicked.connect(lambda: self.change_method("SPC"))
        
        # 默认选中第一个按钮
        self.btn_home.setChecked(True)
        
        # 按新顺序添加按钮到侧边栏
        sidebar_layout.addWidget(self.btn_home)
        sidebar_layout.addWidget(self.btn_pca)
        sidebar_layout.addWidget(self.btn_ica)
        sidebar_layout.addWidget(self.btn_ae)
        sidebar_layout.addWidget(self.btn_dl)
        sidebar_layout.addWidget(self.btn_spc)
        
        # 添加伸缩空间
        sidebar_layout.addStretch()
        
        # 添加退出按钮（也是独立的）
        exit_btn = SidebarButton("退出主页面")
        exit_btn.clicked.connect(self.exit_to_login)
        sidebar_layout.addWidget(exit_btn)
        
        return sidebar
    
    def _create_function_panel(self):
        """创建中间功能面板"""
        # 创建容器
        function_container = QWidget()
        container_layout = QVBoxLayout(function_container)
        container_layout.setContentsMargins(0, 0, 0, 0)
        container_layout.setSpacing(0)
        
        # 创建堆叠小部件以便切换不同的功能面板
        function_stack = QStackedWidget()
        function_stack.setStyleSheet("""
            QStackedWidget {
                background-color: #f5f5f5;
                border-right: 1px solid #e0e0e0;
                border-left: 1px solid #e0e0e0;
            }
        """)
        container_layout.addWidget(function_stack)
        
        # 创建主页功能面板
        home_panel = self._create_home_panel()
        function_stack.addWidget(home_panel)
        
        # 创建ICA功能面板
        ica_panel = self._create_ica_panel()
        function_stack.addWidget(ica_panel)
        
        # 创建AE功能面板
        ae_panel = self._create_ae_panel()
        function_stack.addWidget(ae_panel)
        
        # 创建PCA功能面板
        pca_panel = self._create_pca_panel()  # 替换原来的占位符创建方式
        function_stack.addWidget(pca_panel)
        
        # 创建SPC功能面板（简单占位）
        spc_panel = self._create_spc_panel()
        function_stack.addWidget(spc_panel)
        
        # 创建DL功能面板
        dl_panel = self._create_dl_panel()
        function_stack.addWidget(dl_panel)
        
        # 保存引用和索引
        self.function_stack = function_stack
        self.function_panels = {
            "home": 0,
            "ICA": 1,
            "AE": 2,
            "PCA": 3,  # 原PCA占位符位置改为实际面板
            "SPC": 4,
            "DL": 5
        }
        
        return function_container
    
    def _create_date_workshop_controls(self):
        """创建日期和车间选择控件"""
        control_widget = QWidget()
        control_widget.setFixedHeight(60)  # 减小高度，更适合顶部横条
        control_widget.setStyleSheet("""
            QWidget {
                background-color: #f0f0f0;
                border-bottom: 1px solid #e0e0e0;
            }
            QLabel {
                font-size: 14px;
                color: #333333;
            }
            QDateEdit {
                background-color: white;
                border: 1px solid #d9d9d9;
                border-radius: 4px;
                padding: 4px 8px;
                min-height: 28px;
                min-width: 140px;
                font-size: 13px;
            }
            QDateEdit::drop-down {
                width: 0px;
            }
            QComboBox {
                background-color: white;
                border: 1px solid #d9d9d9;
                border-radius: 4px;
                padding: 4px 8px;
                padding-right: 20px;
                min-height: 28px;
                min-width: 140px;
                font-size: 13px;
            }
            QComboBox QAbstractItemView {
                background-color: white;
                border: 1px solid #d9d9d9;
                selection-background-color: #e6f7ff;
                selection-color: #1890ff;
                outline: none;
            }
            QComboBox::drop-down {
                subcontrol-origin: padding;
                subcontrol-position: top right;
                width: 20px;
                border-left: none;
            }
            QComboBox::down-arrow {
                image: none;
            }
            QDateEdit:focus, QComboBox:focus {
                border-color: #1890ff;
            }
        """)
        
        # 控件布局 - 改为水平布局
        control_layout = QHBoxLayout(control_widget)
        control_layout.setContentsMargins(20, 5, 20, 5)
        control_layout.setSpacing(15)
        
        # 添加日期选择器
        date_container = QHBoxLayout()
        date_label = QLabel("日期:")
        self.date_edit = QDateEdit()
        self.date_edit.setCalendarPopup(False)  # 关闭日历弹出功能
        self.date_edit.setDate(QDate.currentDate())  # 设置当前日期
        self.date_edit.setDisplayFormat("yyyy-MM-dd")  # 设置显示格式
        self.date_edit.setReadOnly(True)  # 设置为只读，只显示日期，不允许编辑
        self.date_edit.setButtonSymbols(QDateEdit.ButtonSymbols.NoButtons)  # 完全移除按钮
        self.date_edit.dateChanged.connect(self.on_date_changed)
        
        date_container.addWidget(date_label)
        date_container.addWidget(self.date_edit)
        control_layout.addLayout(date_container)
        
        # 添加车间选择下拉栏
        workshop_container = QHBoxLayout()
        workshop_label = QLabel("车间:")
        self.workshop_combo = QComboBox()
        
        # 使用内置风格提供下拉箭头
        self.workshop_combo.setStyle(QStyleFactory.create("Fusion"))  # 使用Fusion风格，通常有更好的下拉箭头显示
        
        self.workshop_combo.addItems(["12号机", "11号机", "10号机", "9号机"])
        self.workshop_combo.currentTextChanged.connect(self.on_workshop_changed)
        
        workshop_container.addWidget(workshop_label)
        workshop_container.addWidget(self.workshop_combo)
        control_layout.addLayout(workshop_container)
        
        # 添加弹性空间，使控件居左
        control_layout.addStretch()
        
        return control_widget
    
    def on_date_changed(self, date):
        """处理日期变更事件"""
        self.selected_date = date
        print(f"选择的日期: {date.toString('yyyy-MM-dd')}")
        
    def on_workshop_changed(self, workshop):
        """处理车间变更事件"""
        self.selected_workshop = workshop
        print(f"选择的车间: {workshop}")
    
    def _create_home_panel(self):
        """创建主页功能面板"""
        panel = QWidget()
        layout = QVBoxLayout(panel)
        layout.setContentsMargins(15, 20, 15, 15)  # 减小内边距
        layout.setSpacing(12)  # 减小间距
        
        # 面板标题
        title = QLabel("主页")
        title.setStyleSheet("""
            font-size: 22px;  /* 减小字体 */
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 数据加载按钮
        self.load_data_btn = FunctionButton("加载数据")
        self.load_data_btn.clicked.connect(self.load_data)
        
        # 添加流程图和数据可视化按钮
        self.flow_chart_btn = FunctionButton("流程")
        self.data_viz_btn = FunctionButton("数据可视化")
        
        # 连接按钮点击事件
        self.flow_chart_btn.clicked.connect(self.show_flow_chart)
        self.data_viz_btn.clicked.connect(self.show_data_visualization)
        
        # 添加按钮到布局
        layout.addWidget(self.load_data_btn)
        layout.addWidget(self.flow_chart_btn)
        layout.addWidget(self.data_viz_btn)
        
        # 添加说明文本
        description = QLabel("选择左侧分析方法进行操作")
        description.setStyleSheet("""
            color: #888888;
            font-size: 14px;
            margin-top: 15px;
        """)
        description.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(description)
        
        layout.addStretch()
        
        return panel
    
    def _create_ica_panel(self):
        """创建ICA功能面板"""
        panel = QWidget()
        layout = QVBoxLayout(panel)
        layout.setContentsMargins(15, 20, 15, 15)  # 减小内边距
        layout.setSpacing(20)  # 增加按钮间距
        
        # 面板标题
        title = QLabel("ICA分析")
        title.setStyleSheet("""
            font-size: 22px;  /* 减小字体 */
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 功能按钮 - 使用FunctionButton类
        btn_train_model = FunctionButton("训练模型")
        btn_show_contribution = FunctionButton("显示贡献图")
        btn_diagnosis = FunctionButton("故障诊断报告")
        
        # 连接按钮事件
        btn_train_model.clicked.connect(lambda: self.show_ica_function("train_model"))
        btn_show_contribution.clicked.connect(lambda: self.show_ica_function("show_contribution"))
        btn_diagnosis.clicked.connect(lambda: self.show_ica_function("show_diagnosis"))
        
        # 将按钮存储到字典中
        self.ica_buttons = {
            "train_model": btn_train_model,
            "show_contribution": btn_show_contribution,
            "show_diagnosis": btn_diagnosis
        }
        
        # 添加按钮到布局
        layout.addWidget(btn_train_model)
        layout.addWidget(btn_show_contribution)
        layout.addWidget(btn_diagnosis)
        
        # 添加说明文本
        description = QLabel("请选择ICA分析的操作步骤")
        description.setStyleSheet("""
            color: #888888;
            font-size: 14px;
            margin-top: 15px;
        """)
        description.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(description)
        
        layout.addStretch()
        
        return panel
    
    def _create_ae_panel(self):
        """创建AE功能面板"""
        panel = QWidget()
        layout = QVBoxLayout(panel)
        layout.setContentsMargins(15, 20, 15, 15)
        layout.setSpacing(20)
        
        # 面板标题
        title = QLabel("自动编码器分析")
        title.setStyleSheet("""
            font-size: 22px;
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 添加训练轮数输入区域
        epoch_container = QWidget()
        epoch_layout = QHBoxLayout(epoch_container)
        epoch_layout.setContentsMargins(0, 0, 0, 0)
        
        epoch_label = QLabel("训练轮数:")
        self.epoch_spinbox = QSpinBox()
        self.epoch_spinbox.setRange(1, 1000)
        self.epoch_spinbox.setValue(150)
        self.epoch_spinbox.setFixedWidth(80)
        self.epoch_spinbox.setStyleSheet("""
            QSpinBox {
                background-color: white;
                border: 1px solid #d9d9d9;
                border-radius: 4px;
                padding: 4px;
                min-height: 20px;
            }
            QSpinBox:focus {
                border-color: #1890ff;
            }
        """)
        
        epoch_layout.addWidget(epoch_label)
        epoch_layout.addWidget(self.epoch_spinbox)
        epoch_layout.addStretch()
        
        layout.addWidget(epoch_container)
        
        # 功能按钮
        btn_analyze = FunctionButton("训练与分析")
        btn_re2_chart = FunctionButton("RE²重构监控")
        btn_spe_chart = FunctionButton("SPE异常检测")
        
        # 连接按钮事件
        btn_analyze.clicked.connect(lambda: self.show_ae_function("analyze"))
        btn_re2_chart.clicked.connect(lambda: self.show_ae_function("re2"))
        btn_spe_chart.clicked.connect(lambda: self.show_ae_function("spe"))
        
        # 将按钮存储到字典中
        self.ae_buttons = {
            "analyze": btn_analyze,
            "re2": btn_re2_chart,
            "spe": btn_spe_chart
        }
        
        # 添加按钮到布局
        layout.addWidget(btn_analyze)
        layout.addWidget(btn_re2_chart)
        layout.addWidget(btn_spe_chart)
        
        # 添加说明文本
        description = QLabel("请选择自动编码器分析的操作步骤")
        description.setStyleSheet("""
            color: #888888;
            font-size: 14px;
            margin-top: 15px;
        """)
        description.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(description)
        
        layout.addStretch()
        
        return panel
    
    def _create_placeholder_panel(self, title_text):
        """创建占位面板"""
        panel = QWidget()
        layout = QVBoxLayout(panel)
        layout.setContentsMargins(15, 20, 15, 15)  # 减小内边距
        layout.setSpacing(10)  # 减小间距
        
        # 面板标题
        title = QLabel(title_text)
        title.setStyleSheet("""
            font-size: 22px;  /* 减小字体 */
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 添加说明文本
        description = QLabel("功能开发中...")
        description.setStyleSheet("""
            color: #888888;
            font-size: 14px;
            margin-top: 15px;
        """)
        description.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(description)
        
        layout.addStretch()
        
        return panel
    
    def _create_spc_panel(self):
        """创建SPC功能面板"""
        panel = QWidget()
        layout = QVBoxLayout(panel)
        layout.setContentsMargins(15, 20, 15, 15)
        layout.setSpacing(20)
        
        # 面板标题
        title = QLabel("SPC分析")
        title.setStyleSheet("""
            font-size: 22px;
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 添加控制图类型按钮
        btn_xr = FunctionButton("X-R 控制图")
        btn_xs = FunctionButton("X-S 控制图")
        btn_shewhart = FunctionButton("休哈特控制图")
        
        # 连接按钮事件
        btn_xr.clicked.connect(lambda: self.show_spc_function("Xbar-R"))
        btn_xs.clicked.connect(lambda: self.show_spc_function("Xbar-S"))
        btn_shewhart.clicked.connect(lambda: self.show_spc_function("Shewhart"))
        
        # 将按钮存储到字典中
        self.spc_buttons = {
            "Xbar-R": btn_xr,
            "Xbar-S": btn_xs,
            "Shewhart": btn_shewhart
        }
        
        # 添加按钮到布局
        layout.addWidget(btn_xr)
        layout.addWidget(btn_xs)
        layout.addWidget(btn_shewhart)
        
        # 添加说明文本
        description = QLabel("请选择控制图类型")
        description.setStyleSheet("""
            color: #888888;
            font-size: 14px;
            margin-top: 15px;
        """)
        description.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(description)
        
        layout.addStretch()
        
        return panel
    
    def _create_dl_panel(self):
        """创建深度学习功能面板"""
        panel = QWidget()
        layout = QVBoxLayout(panel)
        layout.setContentsMargins(15, 20, 15, 15)
        layout.setSpacing(20)
        
        # 面板标题
        title = QLabel("Transformer")
        title.setStyleSheet("""
            font-size: 22px;
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 功能按钮
        btn_train = FunctionButton("训练模型")
        btn_predict = FunctionButton("检测")
        
        # 连接按钮事件
        btn_train.clicked.connect(lambda: self.show_dl_function("train"))
        btn_predict.clicked.connect(lambda: self.show_dl_function("predict"))
        
        # 将按钮存储到字典中
        self.dl_buttons = {
            "train": btn_train,
            "predict": btn_predict
        }
        
        # 添加按钮到布局
        layout.addWidget(btn_train)
        layout.addWidget(btn_predict)
        
        # 添加说明文本
        description = QLabel("请选择操作")
        description.setStyleSheet("""
            color: #888888;
            font-size: 14px;
            margin-top: 15px;
        """)
        description.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(description)
        
        layout.addStretch()
        
        return panel
    
    def restore_data_visualization(self):
        """恢复数据可视化显示"""
        if (hasattr(self, 'data_df') and self.data_df is not None and 
            hasattr(self, 'data_viz_index') and self.data_viz_index is not None and 
            self.data_viz_index < self.content_display.count()):
            self.content_display.setCurrentIndex(self.data_viz_index)
            
            # 不自动启用自动翻页功能，使用当前状态
            if hasattr(self, 'auto_flip_btn'):
                self.auto_flip_btn.setChecked(self.auto_flip_enabled)
                
            # 如果启用了自动翻页，则启动定时器
            if self.auto_flip_enabled and hasattr(self, 'viz_timer'):
                if self.viz_timer.isActive():
                    self.viz_timer.stop()
                self.viz_timer.start(5000)
                print("恢复数据可视化: 定时器已启动")
            else:
                print("恢复数据可视化: 未启动定时器 (自动翻页未启用)")
                
            return True
        return False
        
    def change_method(self, method):
        """切换分析方法"""
        if method == self.current_method:
            return
            
        # 如果切换到非主页，并且没有加载数据，提示用户
        if method != "home" and (not hasattr(self, 'data_df') or self.data_df is None):
            QMessageBox.warning(
                self,
                "提示",
                "请先在主页加载数据文件，然后再选择分析方法。"
            )
            method = "home"  # 强制返回主页
        
        # 如果离开数据可视化页面或切换到非主页，停止自动翻页
        if hasattr(self, 'viz_timer') and self.viz_timer.isActive():
            self.viz_timer.stop()
            print("切换功能: 停止自动翻页定时器")
            # 重置自动翻页状态
            self.auto_flip_enabled = False
            if hasattr(self, 'auto_flip_btn'):
                self.auto_flip_btn.setChecked(False)
            
        # 更新当前方法
        self.current_method = method
        
        # 取消选中所有侧边栏按钮
        for btn in [self.btn_home, self.btn_pca, self.btn_ica, self.btn_ae, self.btn_dl, self.btn_spc]:
            btn.setChecked(False)
            
        # 选中当前方法对应的按钮
        if method == "home":
            self.btn_home.setChecked(True)
            # 切换到主页功能面板
            self.function_stack.setCurrentIndex(self.function_panels[method])
            # 恢复数据可视化（如果有）
            if self.restore_data_visualization():
                return
        elif method == "ICA":
            self.btn_ica.setChecked(True)
            # 显示ICA界面但不自动调用加载数据
            self.function_stack.setCurrentIndex(self.function_panels[method])
            self._ensure_ica_widget_created()
            return  # 提前返回，因为已经设置了功能面板和内容显示
        elif method == "AE":
            self.btn_ae.setChecked(True)
            # 显示AE界面但不自动调用加载数据
            self.function_stack.setCurrentIndex(self.function_panels[method])
            self._ensure_ae_widget_created()
            # 重置到欢迎页
            if hasattr(self, 'ae_content_index'):
                self._reset_ae_to_welcome()
            return  # 提前返回，因为已经设置了功能面板和内容显示
        elif method == "PCA":
            self.btn_pca.setChecked(True)
            # 显示PCA界面但不自动调用加载数据
            self.function_stack.setCurrentIndex(self.function_panels[method])
            self._ensure_pca_widget_created()
            return  # 提前返回，因为已经设置了功能面板和内容显示
        elif method == "SPC":
            self.btn_spc.setChecked(True)
            # 显示SPC界面
            self.function_stack.setCurrentIndex(self.function_panels[method])
            self._ensure_spc_widget_created()
            return  # 提前返回，因为已经设置了功能面板和内容显示
        elif method == "DL":
            self.btn_dl.setChecked(True)
            # 显示DL界面
            self.function_stack.setCurrentIndex(self.function_panels[method])
            self._ensure_dl_widget_created()
            return
            
        # 切换功能面板
        self.function_stack.setCurrentIndex(self.function_panels[method])
        
        # 清除右侧显示
        self.content_display.setCurrentIndex(0)
        
    def _ensure_ica_widget_created(self):
        """确保ICA部件已创建并显示在右侧区域"""
        if not self.ica_widget:
            try:
                from Mode.ica import ModernUI
                self.ica_widget = ModernUI(main_window=self)
                
                # 如果已经加载了数据，传递给ICA界面
                if hasattr(self, 'data_df') and self.data_df is not None:
                    self.ica_widget.data_df = self.data_df
                    self.ica_widget.file_path = self.file_path
                    
                    # 传递日期和车间信息
                    if hasattr(self, 'selected_date'):
                        self.ica_widget.selected_date = self.selected_date
                    if hasattr(self, 'selected_workshop'):
                        self.ica_widget.selected_workshop = self.selected_workshop
                
                # 添加到内容显示区域
                if not hasattr(self, 'ica_content_index'):
                    self.ica_content_index = self.content_display.addWidget(self.ica_widget)
                
                # 显示ICA内容
                self.content_display.setCurrentIndex(self.ica_content_index)
                
                # 确保欢迎页面显示
                # ModernUI的_create_ui方法已经创建了欢迎页面，不需要额外操作
            except Exception as e:
                print(f"创建ICA部件失败: {str(e)}")
                QMessageBox.critical(
                    self,
                    "错误",
                    f"加载ICA模块时出错: {str(e)}\n请确保已安装所需的Python库。"
                )
        else:
            # 如果已经存在ICA部件，直接显示并重置到欢迎页
            self.content_display.setCurrentIndex(self.ica_content_index)
            # 重置到欢迎页
            self.ica_widget.reset_to_welcome()
    
    def _ensure_ae_widget_created(self):
        """确保AE内容已创建并显示在右侧区域"""
        if not hasattr(self, 'ae_content_index'):
            try:
                # 创建一个包装容器
                ae_container = QWidget()
                ae_layout = QVBoxLayout(ae_container)
                ae_layout.setContentsMargins(0, 0, 0, 0)
                
                # 创建内容部件
                content_widget = self._extract_content_from_ae()
                ae_layout.addWidget(content_widget)
                
                # 添加到显示区域
                self.content_display.addWidget(ae_container)
                self.ae_content_index = self.content_display.count() - 1
                
                # 显示AE内容
                self.content_display.setCurrentIndex(self.ae_content_index)
                
                # 更新状态提示
                self._update_ae_status("请点击左侧功能按钮进行操作")
                
            except Exception as e:
                print(f"创建AE内容时出错: {str(e)}")
                error_widget = QLabel(f"加载AE界面失败: {str(e)}")
                error_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
                error_widget.setStyleSheet("color: red; font-size: 18px;")
                self.content_display.addWidget(error_widget)
                self.ae_content_index = self.content_display.count() - 1
        else:
            # 显示AE内容
            self.content_display.setCurrentIndex(self.ae_content_index)
    
    def show_ica_function(self, function):
        """显示ICA特定功能"""
        if self.current_method != "ICA":
            self.change_method("ICA")
            # 在change_method中已经调用了_ensure_ica_widget_created，
            # 它会重置到欢迎页，所以这里不需要再次调用
        else:
            # 如果已经在ICA方法中，确保ICA部件已创建，但不重置到欢迎页
            if not hasattr(self, 'ica_widget') or not self.ica_widget:
                self._ensure_ica_widget_created()
            else:
                # 确保显示ICA内容
                self.content_display.setCurrentIndex(self.ica_content_index)
            
        # 取消选中所有功能按钮
        for btn in self.ica_buttons.values():
            btn.setChecked(False)
            
        # 选中当前功能按钮
        self.ica_buttons[function].setChecked(True)
        
        # 执行选定的功能
        if function == "train_model" and hasattr(self.ica_widget, 'show_train_dialog'):
            self.ica_widget.show_train_dialog()
        elif function == "show_contribution" and hasattr(self.ica_widget, 'show_contribution'):
            self.ica_widget.show_contribution()
        elif function == "show_diagnosis" and hasattr(self.ica_widget, 'show_diagnosis'):
            self.ica_widget.show_diagnosis()
    
    def _extract_content_from_ae(self):
        """从AE窗口中提取内容部件，或直接创建内容区域"""
        # 不依赖于AEUI窗口，直接创建内容区域
        if not hasattr(self, 'ae_content_widget'):
            # 创建内容区域
            content = QWidget()
            main_layout = QVBoxLayout(content)
            main_layout.setContentsMargins(0, 0, 0, 0)
            
            # 内容区域容器 - 可滚动
            scroll_area = QScrollArea()
            scroll_area.setWidgetResizable(True)
            scroll_area.setFrameShape(QFrame.Shape.NoFrame)
            scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
            scroll_area.setStyleSheet("""
                QScrollArea {
                    background-color: white;
                    border: none;
                }
            """)
            
            # 创建内容区域容器
            content_container = QWidget()
            content_container.setStyleSheet("""
                QWidget {
                    background-color: white;
                }
            """)
            
            # 内容布局
            content_layout = QVBoxLayout(content_container)
            content_layout.setContentsMargins(20, 20, 20, 20)
            content_layout.setSpacing(15)
            
            # 添加标题和状态区域（设置为不可见）
            header = QLabel("自动编码器故障检测")
            header.setStyleSheet("""
                font-size: 24px;
                font-weight: bold;
                color: #1890ff;
                margin-bottom: 20px;
            """)
            header.setAlignment(Qt.AlignmentFlag.AlignCenter)
            header.setVisible(False)  # 设置为不可见
            content_layout.addWidget(header)
            
            # 添加状态标签（设置为不可见）
            status_label = QLabel("请点击左侧功能按钮进行操作")
            status_label.setStyleSheet("""
                font-size: 16px;
                color: #333333;
                padding: 10px;
            """)
            status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            status_label.setVisible(False)  # 设置为不可见
            content_layout.addWidget(status_label)
            
            # 创建欢迎页
            welcome_widget = QWidget()
            welcome_layout = QVBoxLayout(welcome_widget)
            welcome_layout.setSpacing(20)
            
            # 添加欢迎页标题（这个会与上面的header重复，可以选择隐藏一个）
            title_label = QLabel("自动编码器")
            title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            title_label.setStyleSheet("""
                font-size: 24px;
                font-weight: bold;
                color: #1890ff;
                margin-top: 20px;
            """)
            welcome_layout.addWidget(title_label)
            
            # 添加图标
            icon_label = QLabel()
            icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            # 使用内置图标
            icon = QApplication.style().standardIcon(QStyle.StandardPixmap.SP_ComputerIcon)
            pixmap = icon.pixmap(128, 128)
            icon_label.setPixmap(pixmap)
            welcome_layout.addWidget(icon_label)
            
            # 添加描述
            desc_label = QLabel(
                "自动编码器（Autoencoder）是一种无监督学习的神经网络模型，"
                "通过学习将输入数据压缩到低维表示，然后重建原始数据，"
                "可用于特征提取、降维和异常检测。"
            )
            desc_label.setWordWrap(True)
            desc_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            desc_label.setStyleSheet("""
                font-size: 14px;
                color: #666;
                margin: 10px 20px;
                line-height: 1.5;
            """)
            welcome_layout.addWidget(desc_label)
            
            # 添加功能说明
            functions_frame = QFrame()
            functions_frame.setStyleSheet("""
                background-color: #f5f5f5;
                border-radius: 8px;
                padding: 10px;
            """)
            functions_layout = QVBoxLayout(functions_frame)
            
            functions_title = QLabel("主要功能：")
            functions_title.setStyleSheet("font-size: 16px; font-weight: bold; color: #333;")
            functions_layout.addWidget(functions_title)
            
            functions = [
                ("训练与分析", "训练自动编码器模型并进行数据分析"),
                ("RE²重构监控", "显示最大重构误差的平方监控图"),
                ("SPE异常检测", "显示平方预测误差监控图，用于异常检测")
            ]
            
            for title, desc in functions:
                function_label = QLabel(f"• <b>{title}</b>: {desc}")
                function_label.setStyleSheet("""
                    font-size: 14px;
                    color: #333;
                    margin: 5px 0;
                """)
                functions_layout.addWidget(function_label)
            
            welcome_layout.addWidget(functions_frame)
            
            # 添加使用提示
            tip_label = QLabel("请从左侧功能面板选择相应的操作按钮开始使用")
            tip_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            tip_label.setStyleSheet("""
                font-size: 14px;
                color: #1890ff;
                margin-top: 20px;
                font-weight: bold;
            """)
            welcome_layout.addWidget(tip_label)
            
            # 添加伸缩空间
            welcome_layout.addStretch()
            
            # 将欢迎页添加到内容布局
            content_layout.addWidget(welcome_widget)
            self.ae_welcome_widget = welcome_widget
            
            # 添加进度显示区域
            progress_text = QTextEdit()
            progress_text.setReadOnly(True)
            progress_text.setVisible(False)  # 默认隐藏
            progress_text.setStyleSheet("""
                QTextEdit {
                    background-color: #ffffff;
                    border: 1px solid #d9d9d9;
                    border-radius: 4px;
                    padding: 15px;
                    font-family: 'Consolas', 'Monaco', monospace;
                    font-size: 14px;
                    color: #000000;
                    line-height: 1.6;
                }
            """)
            progress_text.setMinimumHeight(200)
            content_layout.addWidget(progress_text)
            
            # 添加训练损失曲线图
            figure, ax = plt.subplots(figsize=(8, 4))
            canvas = FigureCanvas(figure)
            canvas.setStyleSheet("""
                background-color: white;
                border: 1px solid #d9d9d9;
                border-radius: 4px;
            """)
            canvas.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
            content_layout.addWidget(canvas)
            canvas.setVisible(False)  # 初始隐藏，等到训练开始时显示
            
            # 设置图表属性
            ax.set_title('训练损失曲线', fontsize=16, fontweight='bold')
            ax.set_xlabel('训练轮次', fontsize=14)
            ax.set_ylabel('损失值', fontsize=14)
            ax.grid(True, linestyle='--', alpha=0.7)
            
            # 设置滚动区域
            scroll_area.setWidget(content_container)
            main_layout.addWidget(scroll_area)
            
            # 保存引用，便于后续访问
            self.ae_content_widget = content
            self.ae_content = content_container
            self.ae_content_layout = content_layout
            self.ae_status_label = status_label
            self.ae_progress_text = progress_text
            self.ae_header = header
            self.ae_figure = figure
            self.ae_ax = ax
            self.ae_canvas = canvas
            self.ae_train_losses = []  # 用于存储训练损失
            
            # 初始化分析器和结果
            self.ae_analyzer = None
            self.ae_results = None
            
            return content
        else:
            return self.ae_content_widget
    
    def _extract_content_from_ica(self):
        """从ICA窗口中提取内容部件"""
        if hasattr(self.ica_widget, 'content'):
            return self.ica_widget.content
        elif hasattr(self.ica_widget, 'centralWidget'):
            return self.ica_widget.centralWidget()
        else:
            print("无法从ICA窗口提取内容")
            return None
    
    def exit_to_login(self):
        """退出到登录界面"""
        from loginUi import LoginWindow  # 懒加载登录界面
        self.hide()  # 隐藏当前窗口
        self.login_window = LoginWindow()  # 创建登录窗口实例
        self.login_window.show()  # 显示登录窗口
        self.close()  # 关闭当前窗口

    def on_state_changed(self, new_state):
        """响应全局窗口状态改变"""
        if self.windowState() != new_state:
            self.setWindowState(new_state)

    def changeEvent(self, event):
        if event.type() == event.Type.WindowStateChange:
            # 更新全局状态
            manager.state = self.windowState()
        super().changeEvent(event)
            
    def closeEvent(self, event):
        """窗口关闭事件处理"""
        # 确保停止所有正在运行的定时器
        if hasattr(self, 'viz_timer') and self.viz_timer.isActive():
            self.viz_timer.stop()
        # 处理默认关闭行为
        super().closeEvent(event)

    def load_data(self):
        """加载数据并为所有分析方法准备"""
        # 首先尝试加载默认数据文件
        if os.path.exists(self.default_data_path):
            file_path = self.default_data_path
        else:
            # 如果默认文件不存在，提示用户选择文件
            file_path, _ = QFileDialog.getOpenFileName(
                self,
                "选择数据文件",
                "",
                "Excel files (*.xlsx);;CSV files (*.csv)"
            )
        
        if file_path:
            try:
                # 显示加载中消息
                QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
                
                # 根据文件类型读取数据
                if file_path.endswith('.xlsx'):
                    self.data_df = pd.read_excel(file_path, decimal=',')
                else:
                    self.data_df = pd.read_csv(file_path, header=None)
                    self.data_df.columns = [f'X{i+1}' for i in range(self.data_df.shape[1])]
                
                # 保存文件路径
                self.file_path = file_path
                
                # 从控件获取当前选择的日期和车间
                self.selected_date = self.date_edit.date()
                self.selected_workshop = self.workshop_combo.currentText()
                
                # 保存当前选择的日期和车间
                date_str = self.selected_date.toString('yyyy-MM-dd')
                workshop = self.selected_workshop
                
                # 将日期和车间信息添加到数据中
                self.data_info = {
                    'date': date_str,
                    'workshop': workshop,
                    'file_path': file_path
                }
                
                # 初始化页面状态
                self.current_viz_page = 0
                self.total_viz_pages = (len(self.data_df.columns) + 5) // 6
                
                # 显示数据可视化
                self._create_data_visualization()
                
                # 恢复光标
                QApplication.restoreOverrideCursor()
                
            except Exception as e:
                QApplication.restoreOverrideCursor()
                QMessageBox.critical(
                    self,
                    "错误",
                    f"加载数据失败: {str(e)}"
                )
                
    def _create_data_visualization(self):
        """创建数据可视化并显示在右侧区域"""
        # 创建可视化容器
        viz_container = QWidget()
        viz_layout = QVBoxLayout(viz_container)
        viz_layout.setContentsMargins(20, 20, 20, 20)
        viz_layout.setSpacing(15)
        
        # 筛选有效数据的列
        valid_columns = []
        for col in self.data_df.columns:
            data = self.data_df[col].dropna()
            if len(data) > 0:
                valid_columns.append(col)
        
        # 如果是第一次创建，初始化页码状态
        if not hasattr(self, 'current_viz_page'):
            self.current_viz_page = 0
        if not hasattr(self, 'total_viz_pages'):
            self.total_viz_pages = (len(valid_columns) + 5) // 6
        
        # 添加标题
        title = QLabel("数据可视化概览")
        title.setStyleSheet("""
            font-size: 22px;
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        viz_layout.addWidget(title)
        
        # 创建滚动区域
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_content = QWidget()
        scroll_layout = QVBoxLayout(scroll_content)
        scroll_layout.setContentsMargins(0, 0, 0, 0)
        scroll_layout.setSpacing(20)
        
        # 保存滚动区域的引用，以便在翻页时控制滚动位置
        self.viz_scroll_area = scroll_area
        
        # 根据当前页码选择要显示的列
        start_idx = self.current_viz_page * 6
        end_idx = min(start_idx + 6, len(valid_columns))
        current_valid_columns = valid_columns[start_idx:end_idx]
        
        # 创建数据分布图表
        # 计算实际需要的子图数量
        n_plots = len(current_valid_columns)
        rows = (n_plots + 2) // 3  # 确保至少有1行，最多2行
        rows = max(1, min(rows, 2))
        
        # 创建适应当前有效列数量的子图
        fig = None
        if n_plots > 0:
            fig, axes = plt.subplots(rows, 3, figsize=(12, 4*rows))
            fig.tight_layout(pad=3.0)
            plt.subplots_adjust(hspace=0.4)
            
            # 确保axes是数组，即使只有一个子图
            if n_plots == 1:
                axes = np.array([axes])
            
            # 确保axes是平坦的二维数组
            axes = np.array(axes).reshape(-1)
            
            # 绘制当前页的列
            for i, col in enumerate(current_valid_columns):
                ax = axes[i]
                
                # 检查数据类型，对数值型数据绘制直方图
                if np.issubdtype(self.data_df[col].dtype, np.number):
                    # 移除极端值后绘制直方图
                    data = self.data_df[col].dropna()
                    # 计算IQR并过滤异常值
                    q1, q3 = np.percentile(data, [25, 75])
                    iqr = q3 - q1
                    upper_bound = q3 + 1.5 * iqr
                    lower_bound = q1 - 1.5 * iqr
                    filtered_data = data[(data >= lower_bound) & (data <= upper_bound)]
                    
                    if len(filtered_data) > 0:
                        ax.hist(filtered_data, bins=20, alpha=0.7, color='skyblue', edgecolor='black')
                        ax.set_title(col, fontsize=10)
                        ax.set_xlabel('值', fontsize=8)
                        ax.set_ylabel('频数', fontsize=8)
                        ax.tick_params(axis='both', which='major', labelsize=8)
                        ax.grid(True, linestyle='--', alpha=0.7)
                    else:
                        ax.set_visible(False)  # 隐藏无效数据的子图
                else:
                    # 对非数值型数据显示类别统计
                    data = self.data_df[col].value_counts().head(10)
                    if len(data) > 0:
                        bar_width = 0.6
                        ax.bar(range(len(data)), data.values, width=bar_width, color='lightgreen', edgecolor='black')
                        ax.set_xticks(range(len(data)))
                        ax.set_xticklabels(data.index, rotation=45, ha='right', fontsize=7)
                        ax.set_title(f"{col} (前10类)", fontsize=10)
                        ax.set_ylabel('计数', fontsize=8)
                        ax.tick_params(axis='both', which='major', labelsize=8)
                        ax.grid(True, axis='y', linestyle='--', alpha=0.7)
                    else:
                        ax.set_visible(False)  # 隐藏无效数据的子图
            
            # 隐藏未使用的子图
            for j in range(i+1, len(axes)):
                axes[j].set_visible(False)
            
            # 创建图表容器并添加到布局
            if fig:
                canvas = FigureCanvas(fig)
                canvas.setMinimumHeight(400)
                
                # 添加图表标题（显示当前页码信息）
                if len(valid_columns) > 0:
                    current_range = f"{start_idx + 1}-{end_idx}"
                    chart_title = QLabel(f"数据分布可视化（第{current_range}列，共{len(valid_columns)}列）")
                    chart_title.setStyleSheet("font-size: 16px; font-weight: bold; color: #1890ff;")
                    chart_title.setAlignment(Qt.AlignmentFlag.AlignCenter)
                    scroll_layout.addWidget(chart_title)
                    scroll_layout.addWidget(canvas)
                else:
                    no_data_label = QLabel("所有列均无有效数据可供可视化")
                    no_data_label.setStyleSheet("font-size: 16px; color: #ff4d4f; margin: 20px;")
                    no_data_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
                    scroll_layout.addWidget(no_data_label)
        else:
            # 当前页没有有效列
            no_data_label = QLabel("当前页无有效数据可供可视化")
            no_data_label.setStyleSheet("font-size: 16px; color: #ff4d4f; margin: 20px;")
            no_data_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            scroll_layout.addWidget(no_data_label)
        
        # 添加翻页控制区域
        nav_container = QWidget()
        nav_layout = QHBoxLayout(nav_container)
        nav_layout.setContentsMargins(0, 10, 0, 0)
        
        # 保存为类成员变量
        self.prev_viz_btn = QPushButton("上一页")
        self.next_viz_btn = QPushButton("下一页")
        self.page_label = QLabel()
        
        # 更新总页数
        self.total_viz_pages = (len(valid_columns) + 5) // 6
        if self.total_viz_pages == 0:
            self.total_viz_pages = 1  # 至少有一页
        
        # 确保当前页不超过总页数
        if self.current_viz_page >= self.total_viz_pages:
            self.current_viz_page = self.total_viz_pages - 1
        
        # 设置按钮状态
        self.prev_viz_btn.setEnabled(self.current_viz_page > 0)
        self.next_viz_btn.setEnabled(self.current_viz_page < self.total_viz_pages - 1)
        
        # 设置页码显示
        self.page_label.setText(f"第 {self.current_viz_page + 1}/{self.total_viz_pages} 页")
        self.page_label.setStyleSheet("font-size: 14px; margin: 0 15px;")
        self.page_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 设置按钮样式
        button_style = """
            QPushButton {
                background-color: #e6f7ff;
                color: #333333;
                border: 1px solid #91d5ff;
                padding: 5px 15px;
                border-radius: 4px;
            }
            QPushButton:disabled {
                background-color: #f5f5f5;
                color: #bfbfbf;
                border: 1px solid #d9d9d9;
            }
            QPushButton:hover:!disabled {
                background-color: white;
                border-color: #1890ff;
                color: #1890ff;
            }
        """
        self.prev_viz_btn.setStyleSheet(button_style)
        self.next_viz_btn.setStyleSheet(button_style)
        
        # 连接翻页事件
        self.prev_viz_btn.clicked.connect(self._prev_viz_page)
        self.next_viz_btn.clicked.connect(self._next_viz_page)
        
        # 设置对象名称，便于调试
        self.prev_viz_btn.setObjectName("prev_viz_btn")
        self.next_viz_btn.setObjectName("next_viz_btn")
        
        # 添加按钮到导航容器
        nav_layout.addStretch()
        nav_layout.addWidget(self.prev_viz_btn)
        nav_layout.addWidget(self.page_label)
        nav_layout.addWidget(self.next_viz_btn)
        
        # 添加自动翻页开关按钮
        self.auto_flip_btn = QPushButton("自动轮播")
        self.auto_flip_btn.setCheckable(True)
        # 确保按钮状态与当前自动翻页设置一致
        current_auto_flip = self.auto_flip_enabled if hasattr(self, 'auto_flip_enabled') else False
        self.auto_flip_btn.setChecked(current_auto_flip)
        # 先断开之前可能连接的信号
        try:
            self.auto_flip_btn.clicked.disconnect()
        except:
            pass
        # 连接点击事件
        self.auto_flip_btn.clicked.connect(self.toggle_auto_flip)
        print(f"已连接自动翻页按钮点击事件，当前状态: {'开启' if current_auto_flip else '关闭'}")
        self.auto_flip_btn.setStyleSheet("""
            QPushButton {
                background-color: #f0f0f0;
                border: 1px solid #ddd;
                border-radius: 4px;
                padding: 5px 10px;
                color: #333;
                font-size: 12px;
            }
            QPushButton:checked {
                background-color: #1890ff;
                color: white;
            }
        """)
        nav_layout.addWidget(self.auto_flip_btn)
        nav_layout.addStretch()
        
        # 添加导航容器到主布局
        scroll_layout.addWidget(nav_container)
        
        # 设置滚动区域
        scroll_area.setWidget(scroll_content)
        viz_layout.addWidget(scroll_area)
        
        # 保存有效列列表以供翻页使用
        self.valid_columns = valid_columns
        
        # 清除当前右侧显示区域内容，添加数据可视化
        if hasattr(self, 'data_viz_index') and self.data_viz_index is not None and self.data_viz_index < self.content_display.count():
            # 如果已有可视化页面，替换它
            old_widget = self.content_display.widget(self.data_viz_index)
            if old_widget:  # 确保widget存在
                self.content_display.removeWidget(old_widget)
                old_widget.deleteLater()
            self.content_display.insertWidget(self.data_viz_index, viz_container)
        else:
            # 否则添加新的可视化页面
            self.content_display.addWidget(viz_container)
            self.data_viz_index = self.content_display.count() - 1
            
        # 显示可视化页面
        self.content_display.setCurrentIndex(self.data_viz_index)
        
        # 如果在主页，确保主页功能面板被选中
        if self.current_method == "home":
            self.function_stack.setCurrentIndex(self.function_panels["home"])
            
        # 根据自动翻页设置启动定时器
        if self.auto_flip_enabled and hasattr(self, 'viz_timer'):
            if self.viz_timer.isActive():
                self.viz_timer.stop()
            self.viz_timer.start(5000)
    
    def _create_top_control_bar(self):
        """创建顶部控制栏，包含标题、最小化和关闭按钮"""
        top_bar = QWidget()
        top_bar.setFixedHeight(40)
        # 设置鼠标样式为指针，表示可拖动
        top_bar.setCursor(Qt.CursorShape.PointingHandCursor)
        # 设置顶部控制栏的鼠标事件，使整个顶部控制栏可拖动
        top_bar.mousePressEvent = self.title_bar_mouse_press
        top_bar.mouseDoubleClickEvent = self.title_bar_double_click
        # 添加鼠标移动事件处理器
        top_bar.mouseMoveEvent = self.title_bar_mouse_move
        top_bar.setStyleSheet("""
            QWidget {
                background-color: #1890ff;
                border: none;
            }
            QPushButton {
                color: white;
                background-color: transparent;
                font-size: 16px;
                font-weight: bold;
                border: none;
                border-radius: 15px;
            }
            QPushButton:hover {
                background-color: rgba(255, 255, 255, 0.2);
            }
            QPushButton:pressed {
                background-color: rgba(255, 255, 255, 0.1);
            }
        """)
        
        # 水平布局
        layout = QHBoxLayout(top_bar)
        layout.setContentsMargins(10, 0, 10, 0)
        
        # 添加标题容器
        title_container = QWidget()
        title_layout = QHBoxLayout(title_container)
        title_layout.setContentsMargins(0, 0, 0, 0)
        
        # 添加标题
        title = QLabel("智能诊断系统")
        title.setStyleSheet("""
            color: white;
            font-size: 16px;
            font-weight: bold;
        """)
        title_layout.addWidget(title)
        
        layout.addWidget(title_container)
        
        # 添加弹性空间
        layout.addStretch()
        
        # 添加使用手册按钮
        manual_button = QPushButton("使用手册")
        manual_button.setFixedSize(80, 30)
        manual_button.clicked.connect(self.show_about)
        layout.addWidget(manual_button)
        
        # 最小化按钮
        min_button = QPushButton("—")
        min_button.setFixedSize(30, 30)
        min_button.clicked.connect(self.showMinimized)
        
        # 最大化/恢复按钮
        self.max_restore_button = QPushButton("□")
        self.max_restore_button.setFixedSize(30, 30)
        self.max_restore_button.clicked.connect(self.toggle_maximize)
        
        # 关闭按钮
        close_button = QPushButton("×")
        close_button.setFixedSize(30, 30)
        close_button.clicked.connect(self.close)
        
        # 添加按钮到布局
        layout.addWidget(min_button)
        layout.addWidget(self.max_restore_button)
        layout.addWidget(close_button)
        
        return top_bar
    
    def title_bar_mouse_press(self, event):
        """标题栏的鼠标点击事件，用于拖动窗口"""
        if self.window().isMaximized():
            return
        if event.button() == Qt.MouseButton.LeftButton:
            # 获取主窗口
            main_window = self.window()
            # 计算拖动位置
            main_window.drag_position = event.globalPosition().toPoint() - main_window.frameGeometry().topLeft()
            event.accept()
    
    def title_bar_mouse_move(self, event):
        """标题栏的鼠标移动事件，用于拖动窗口"""
        if self.isMaximized():
            return
        if event.buttons() == Qt.MouseButton.LeftButton and hasattr(self, 'drag_position'):
            # 使用窗口的move方法移动整个窗口
            self.window().move(event.globalPosition().toPoint() - self.drag_position)
            event.accept()
    
    def title_bar_double_click(self, event):
        """标题栏的双击事件，用于最大化/恢复窗口"""
        if event.button() == Qt.MouseButton.LeftButton:
            self.toggle_maximize()
            event.accept()
    
    def toggle_maximize(self):
        """切换窗口最大化/恢复状态"""
        if self.isMaximized():
            self.showNormal()
            self.max_restore_button.setText("□")
        else:
            self.showMaximized()
            self.max_restore_button.setText("❐")
            
    def show_about(self):
        """显示关于对话框，渲染README.md内容"""
        try:
            # 创建对话框
            about_dialog = QDialog(self)
            about_dialog.setWindowTitle("关于华泰智能诊断系统")
            about_dialog.setMinimumSize(800, 600)
            
            # 创建布局
            layout = QVBoxLayout(about_dialog)
            
            # 创建滚动区域
            scroll_area = QScrollArea()
            scroll_area.setWidgetResizable(True)
            scroll_area.setStyleSheet("""
                QScrollArea {
                    border: none;
                    background-color: white;
                }
            """)
            
            # 创建内容容器
            content_widget = QWidget()
            content_layout = QVBoxLayout(content_widget)
            
            # 读取README.md文件
            readme_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'README.md')
            if os.path.exists(readme_path):
                with open(readme_path, "r", encoding="utf-8") as f:
                    readme_content = f.read()
            else:
                readme_content = "README.md文件不存在"
            
            # 创建文本浏览器显示内容
            text_browser = QTextBrowser()
            text_browser.setOpenExternalLinks(True)  # 允许打开外部链接
            text_browser.document().setDefaultStyleSheet("""
                a { color: #1890ff; text-decoration: none; cursor: pointer; }
                a:hover { text-decoration: underline; color: #40a9ff; }
                a:visited { color: #722ed1; }
            """)
            
            # 设置样式
            text_browser.setStyleSheet("""
                QTextBrowser {
                    border: none;
                    background-color: white;
                    font-family: "Microsoft YaHei", Arial, sans-serif;
                    font-size: 14px;
                    line-height: 1.6;
                }
                h1 { font-size: 24px; color: #1890ff; }
                h2 { font-size: 20px; color: #1890ff; }
                h3 { font-size: 16px; font-weight: bold; }
            """)
            text_browser.setOpenLinks(True)  # 确保链接可点击
            
            # 简单的Markdown到HTML转换
            html_content = self._convert_markdown_to_html(readme_content)
            text_browser.setHtml(html_content)
            
            # 添加到布局
            content_layout.addWidget(text_browser)
            scroll_area.setWidget(content_widget)
            layout.addWidget(scroll_area)
            
            # 添加关闭按钮
            button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
            button_box.rejected.connect(about_dialog.reject)
            layout.addWidget(button_box)
            
            # 显示对话框
            about_dialog.exec()
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"显示关于信息时出错: {str(e)}")
    
    def _convert_markdown_to_html(self, markdown_text):
        """使用markdown2进行Markdown到HTML转换"""
        try:
            import markdown2
            
            # 配置markdown2转换选项
            extras = [
                "fenced-code-blocks",  # 支持围栏式代码块
                "tables",              # 支持表格
                "task-lists",          # 支持任务列表
                "code-friendly",       # 更好的代码处理
                "cuddled-lists",       # 更好的列表处理
                "break-on-newline",    # 支持换行
                "header-ids",          # 标题ID
                "footnotes",           # 支持脚注
                "smarty-pants",        # 智能标点
                "markdown-in-html"     # 支持HTML中的Markdown
            ]
            
            # 转换Markdown为HTML
            html = markdown2.markdown(markdown_text, extras=extras)
            
            # 添加自定义样式
            styled_html = f"""<html>
            <head>
                <style>
                    body {{font-family: "Microsoft YaHei", Arial, sans-serif;}}
                    h1, h2 {{color: #1890ff;}}
                    h1 {{font-size: 24px;}}
                    h2 {{font-size: 20px;}}
                    h3 {{font-size: 16px; font-weight: bold;}}
                    pre {{background-color: #f6f8fa; padding: 16px; border-radius: 6px;}}
                    code {{font-family: Consolas, monospace;}}
                    table {{border-collapse: collapse; width: 100%; margin: 16px 0;}}
                    th, td {{border: 1px solid #ddd; padding: 8px; text-align: left;}}
                    th {{background-color: #f6f8fa;}}
                    blockquote {{border-left: 4px solid #ddd; margin: 0; padding-left: 16px; color: #666;}}
                    img {{max-width: 100%; height: auto;}}
                    .task-list-item {{list-style-type: none;}}
                    .task-list-item input {{margin-right: 8px;}}
                </style>
            </head>
            <body>
                {html}
            </body>
            </html>"""
            
            return styled_html
            
        except ImportError:
            # 如果markdown2未安装，返回简单的纯文本显示
            return f"<html><body><pre>{markdown_text}</pre></body></html>"
        except Exception as e:
            # 处理其他可能的错误
            return f"<html><body><p>转换出错: {str(e)}</p></body></html>"
            
    def _next_viz_page(self):
        """显示下一页数据可视化"""
        if self.current_viz_page < self.total_viz_pages - 1:
            self.current_viz_page += 1
            plt.close('all')  # 关闭所有图表
            self._create_data_visualization()
            
            # 确保滚动区域回到顶部
            if hasattr(self, 'viz_scroll_area'):
                self.viz_scroll_area.verticalScrollBar().setValue(0)
            
            # 重新启动定时器（如果启用了自动翻页）
            if self.auto_flip_enabled:
                self.viz_timer.start(5000)
            
    def _prev_viz_page(self):
        """显示上一页数据可视化"""
        if self.current_viz_page > 0:
            self.current_viz_page -= 1
            plt.close('all')  # 关闭所有图表
            self._create_data_visualization()
            
            # 确保滚动区域回到顶部
            if hasattr(self, 'viz_scroll_area'):
                self.viz_scroll_area.verticalScrollBar().setValue(0)
            
            # 重新启动定时器（如果启用了自动翻页）
            if self.auto_flip_enabled:
                self.viz_timer.start(5000)
    
    # 添加鼠标事件处理，使无边框窗口可以拖动
    def mousePressEvent(self, event):
        # 如果窗口已最大化，则不进行拖动
        if self.isMaximized():
            return
            
        if event.button() == Qt.MouseButton.LeftButton:
            # 只有点击了顶部区域才进行拖动
            if event.position().y() <= 40:  # 顶部控制栏的高度
                self.drag_position = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
                event.accept()

    def mouseMoveEvent(self, event):
        # 如果窗口已最大化，则不进行拖动
        if self.isMaximized():
            return
            
        if event.buttons() == Qt.MouseButton.LeftButton and hasattr(self, 'drag_position'):
            # 使用窗口的move方法移动整个窗口
            self.window().move(event.globalPosition().toPoint() - self.drag_position)
            event.accept()

    def _ensure_spc_widget_created(self):
        """确保SPC部件已创建并显示在右侧区域"""
        if not self.spc_widget:
            try:
                from Mode.spc import SPCWidget
                self.spc_widget = SPCWidget(main_window=self)
                
                # SPC部件现在使用独立的数据源，不再从主窗口获取数据
                
                # 添加到内容显示区域
                if not hasattr(self, 'spc_content_index'):
                    self.spc_content_index = self.content_display.addWidget(self.spc_widget)
                
                # 显示SPC内容
                self.content_display.setCurrentIndex(self.spc_content_index)
            except Exception as e:
                print(f"创建SPC部件失败: {str(e)}")
                QMessageBox.critical(
                    self,
                    "错误",
                    f"加载SPC模块时出错: {str(e)}\n请确保已安装所需的Python库。"
                )
        else:
            # 如果已经存在SPC部件，直接显示
            self.content_display.setCurrentIndex(self.spc_content_index)
    
    def show_spc_function(self, function):
        """显示SPC特定功能"""
        if self.current_method != "SPC":
            self.change_method("SPC")
            
        # 取消选中所有功能按钮
        for btn in self.spc_buttons.values():
            btn.setChecked(False)
            
        # 选中当前功能按钮
        self.spc_buttons[function].setChecked(True)
        
        # 确保SPC部件已创建
        if not hasattr(self, 'spc_widget') or not self.spc_widget:
            try:
                from Mode.spc import SPCWidget
                self.spc_widget = SPCWidget(main_window=self)
                
                # SPC部件现在使用独立的数据源，不再从主窗口获取数据
                
                # 添加到内容显示区域
                if not hasattr(self, 'spc_content_index'):
                    self.spc_content_index = self.content_display.addWidget(self.spc_widget)
                
                # 显示SPC内容
                self.content_display.setCurrentIndex(self.spc_content_index)
            except Exception as e:
                print(f"创建SPC内容时出错: {str(e)}")
                error_widget = QLabel(f"加载SPC界面失败: {str(e)}")
                error_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
                error_widget.setStyleSheet("color: red; font-size: 18px;")
                self.content_display.addWidget(error_widget)
                self.spc_content_index = self.content_display.count() - 1
                return
        # 如果SPC部件已存在，不再更新其数据，使用其独立数据源
        
        # 显示SPC内容
        self.content_display.setCurrentIndex(self.spc_content_index)
        
        # 执行选定的功能
        if function == "Xbar-R" and hasattr(self.spc_widget, 'show_Xbar_R'):
            self.spc_widget.show_Xbar_R()
        elif function == "Xbar-S" and hasattr(self.spc_widget, 'show_Xbar_S'):
            self.spc_widget.show_Xbar_S()
        elif function == "Shewhart" and hasattr(self.spc_widget, 'show_Shewhart'):
            self.spc_widget.show_Shewhart()
    
    def show_dl_function(self, function):
        """显示DL特定功能"""
        if self.current_method != "DL":
            self.change_method("DL")
            
        # 取消选中所有功能按钮
        for btn in self.dl_buttons.values():
            btn.setChecked(False)
            
        # 选中当前功能按钮
        self.dl_buttons[function].setChecked(True)
        
        # 确保DL部件已创建
        if not hasattr(self, 'dl_widget') or not self.dl_widget:
            try:
                from Mode.dl import DLWidget
                self.dl_widget = DLWidget(main_window=self)
                
                # 如果已经加载了数据，传递给DL界面
                if hasattr(self, 'data_df') and self.data_df is not None:
                    self.dl_widget.data_df = self.data_df
                    self.dl_widget.file_path = self.file_path
                
                # 添加到内容显示区域
                if not hasattr(self, 'dl_content_index'):
                    self.dl_content_index = self.content_display.addWidget(self.dl_widget)
                
                # 显示DL内容
                self.content_display.setCurrentIndex(self.dl_content_index)
            except Exception as e:
                print(f"创建DL部件失败: {str(e)}")
                QMessageBox.critical(
                    self,
                    "错误",
                    f"加载DL模块时出错: {str(e)}\n请确保已安装所需的Python库。"
                )
        else:
            # 如果已经存在DL部件，直接显示
            self.content_display.setCurrentIndex(self.dl_content_index)

    def show_ae_function(self, function):
        """显示AE特定功能，直接在主界面中实现，不依赖于aeUi.py"""
        if self.current_method != "AE":
            self.change_method("AE")
            
        # 取消选中所有功能按钮
        for btn in self.ae_buttons.values():
            btn.setChecked(False)
            
        # 根据选择的功能执行不同操作
        self.stat_name = ""  # 初始化 stat_name

        # 选中当前功能按钮
        if function in self.ae_buttons:
            self.ae_buttons[function].setChecked(True)

        # 确保AE内容区域已创建
        if not hasattr(self, 'ae_content_index'):
            try:
                # 创建一个包装容器
                ae_container = QWidget()
                ae_layout = QVBoxLayout(ae_container)
                ae_layout.setContentsMargins(0, 0, 0, 0)
                
                # 创建内容部件
                content_widget = self._extract_content_from_ae()
                ae_layout.addWidget(content_widget)
                
                # 添加到显示区域
                self.content_display.addWidget(ae_container)
                self.ae_content_index = self.content_display.count() - 1
            except Exception as e:
                print(f"创建AE内容时出错: {str(e)}")
                error_widget = QLabel(f"加载AE界面失败: {str(e)}")
                error_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
                error_widget.setStyleSheet("color: red; font-size: 18px;")
                self.content_display.addWidget(error_widget)
                self.ae_content_index = self.content_display.count() - 1
                return
        
        # 显示AE内容
        self.content_display.setCurrentIndex(self.ae_content_index)
        
        # 清空之前的内容
        self._clear_ae_content()
        
        # 导入必要的模块
        from aeMode import run_ae_re2_analysis, run_ae_spe_analysis, run_fault_detection
        import matplotlib.pyplot as plt
        
        # 根据选择的功能执行不同操作
        if function == "analyze":
            if not hasattr(self, 'file_path') or not self.file_path:
                self._update_ae_status("请先加载数据文件", 'error')
                return  # 如果没有加载数据，直接返回，避免后续错误
                
            # 更新状态
            self._update_ae_status("正在分析数据...", 'info')
            # 显示进度文本区域
            self.ae_progress_text.clear()
            self.ae_progress_text.setVisible(True)
            
            # 初始化训练损失列表
            self.ae_train_losses = []
            
            # 显示训练损失曲线图
            self.ae_canvas.setVisible(True)
            self.ae_ax.clear()
            self.ae_ax.set_title('训练损失曲线', fontsize=16, fontweight='bold')
            self.ae_ax.set_xlabel('训练轮次', fontsize=14)
            self.ae_ax.set_ylabel('损失值', fontsize=14)
            self.ae_ax.grid(True, linestyle='--', alpha=0.7)
            self.ae_canvas.draw()
            
            # 显示初始化动画
            self._update_ae_progress("🚀 自编码器分析系统初始化...")
            self._update_ae_progress("⚡ 正在准备数据预处理...")
            self._update_ae_progress("-" * 50)  # 分隔线
            self._update_ae_progress("📊 开始数据分析流程")
            self._update_ae_progress("1. 数据加载与标准化")

            # 获取训练轮数
            epochs = self.epoch_spinbox.value()
            
            try:
                # 更新进度显示区域为终端样式
                self.ae_progress_text.setStyleSheet("""
                    QTextEdit {
                        background-color: #ffffff;
                        border: 1px solid #d9d9d9;
                        border-radius: 4px;
                        padding: 15px;
                        font-family: 'Consolas', 'Monaco', monospace;
                        font-size: 14px;
                        color: #000000;
                        line-height: 1.6;
                    }
                """)
                
                # 执行分析
                def progress_callback(message):
                    # 更新进度文本
                    self._update_ae_progress(message)
                    
                    # 检查消息是否包含训练轮次和损失信息
                    if "训练轮次" in message and "损失:" in message:
                        try:
                            # 提取损失值
                            loss_str = message.split("损失:")[1].strip()
                            loss = float(loss_str)
                            
                            # 添加到损失列表
                            self.ae_train_losses.append(loss)
                            
                            # 更新损失曲线图
                            self.ae_ax.clear()
                            epochs = range(1, len(self.ae_train_losses) + 1)
                            self.ae_ax.plot(epochs, self.ae_train_losses, 'b-', linewidth=2, label='训练损失')
                            
                            # 设置图表属性
                            self.ae_ax.set_title('训练损失曲线', fontsize=16, fontweight='bold')
                            self.ae_ax.set_xlabel('训练轮次', fontsize=14)
                            self.ae_ax.set_ylabel('损失值', fontsize=14)
                            self.ae_ax.grid(True, linestyle='--', alpha=0.7)
                            self.ae_ax.legend(loc='upper right', fontsize=12)
                            
                            # 设置Y轴范围，使图表更稳定
                            if len(self.ae_train_losses) > 1:
                                y_min = min(self.ae_train_losses)
                                y_max = max(self.ae_train_losses[1:]) if len(self.ae_train_losses) > 1 else max(self.ae_train_losses)
                                y_margin = (y_max - y_min) * 0.1
                                self.ae_ax.set_ylim([max(0, y_min - y_margin), y_max + y_margin])
                            
                            # 刷新画布
                            self.ae_canvas.draw()
                            QApplication.processEvents()  # 确保UI更新
                        except Exception as e:
                            print(f"更新损失曲线出错: {str(e)}")
                
                # 运行分析
                self.ae_results = run_fault_detection(self.file_path, progress_callback, epochs=epochs)
                
                if self.ae_results:
                    self.ae_analyzer = self.ae_results['analyzer']
                    self._update_ae_status("✨ 分析完成！", 'success')
                    
                    # 移除完成动画效果
                    # for i in range(5):
                    #     self._update_ae_progress("🎉 " * (i + 1))
                    #     time.sleep(0.1)
                    # self._update_ae_progress("\n训练过程已完成！\n")
                    
                    # 显示分析结果摘要
                    self._show_ae_summary()
                else:
                    self._update_ae_status("❌ 分析失败", 'error')
            except Exception as e:
                self._update_ae_status(f"❌ 分析出错: {str(e)}", 'error')
                import traceback
                traceback.print_exc()
        elif function == "re2":
            # 显示RE²监控图
            if not hasattr(self, 'ae_results') or not self.ae_results:
                self._update_ae_status("请先完成数据分析", 'warning')
                return
                
            try:
                # 设置统计量名称
                self.stat_name = "RE²"
 
                # 更新标题
                title_label = QLabel("RE²重构误差监控图表")
                title_label.setStyleSheet("""
                    font-size: 18px;
                    font-weight: bold;
                    color: #333;
                    margin-bottom: 15px;
                """)
                self.ae_content_layout.addWidget(title_label)
                
                # 创建图表
                fig = plt.figure(figsize=(12, 7))
                self.ax = fig.add_subplot(111)

                # 初始化动态绘制元素
                self.line, = self.ax.plot([], [], 'b-', linewidth=1, alpha=0.6, label='RE²')
                self.scatter = self.ax.scatter([], [], c='b', s=30, alpha=0.6)

                # 添加控制限
                control_limit = self.ae_results['re2_control_limit']
                self.ax.axhline(y=control_limit, color='r', linestyle='--',
                               label=f'控制限 ({control_limit:.3f})', linewidth=2)

                # 设置图表属性
                self.ax.set_title('RE²监控图表')
                self.ax.set_xlabel('样本编号')
                self.ax.set_ylabel('RE²')
                self.ax.legend()
                self.ax.grid(True, alpha=0.3)
                
                # 创建画布
                self.canvas = FigureCanvas(fig)
                self.canvas.setMinimumHeight(350)  # Further reduced minimum height
                self.canvas.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) # Allow vertical expansion


                # 创建图表容器
                chart_container = QWidget()
                chart_layout = QVBoxLayout(chart_container)
                chart_layout.addWidget(self.canvas)
                
                # 添加到界面
                self.ae_content_layout.addWidget(chart_container)
                
                # 准备实时更新数据
                self.monitoring_data = self.ae_results['re2_test']
                self.anomalies = self.ae_results['re2_anomalies']['mask']
                self.current_index = 0

                # 添加实时统计信息文本框
                self.anomaly_info = QTextEdit()
                self.anomaly_info.setMinimumHeight(100)  # Further reduced minimum height
                self.anomaly_info.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) # Allow expansion, but prefer fixed
                self.anomaly_info.setReadOnly(True)
                self.anomaly_info.setStyleSheet("""
                    QTextEdit {
                        font-family: 'Microsoft YaHei', sans-serif;
                        font-size: 14px;
                        line-height: 1.5;
                        padding: 10px;
                        background-color: #f8f9fa;
                        border: 1px solid #e9ecef;
                        border-radius: 4px;
                    }
                """)
                self.ae_content_layout.addWidget(self.anomaly_info)

                # 启动定时器
                if not hasattr(self, 'ae_timer'):
                    self.ae_timer = QTimer()
                    self.ae_timer.timeout.connect(self._update_ae_chart)
                self.ae_timer.start(50)

                # 添加异常统计信息文本 (Combined with real-time stats)
                anomalies = self.ae_results['re2_anomalies']
                anomaly_count = anomalies['count']
                anomaly_indices = np.where(anomalies['mask'])[0]
                control_limit = self.ae_results['re2_control_limit']
                stat_name = "RE²"

                anomaly_text = f"{stat_name}统计量分析结果：\n"
                anomaly_text += f"• 控制限：{control_limit:.4f}\n"
                anomaly_text += f"• 检测到的异常样本数：{anomaly_count}\n"

                if anomaly_count > 0:
                    anomaly_text += f"• 异常数据索引：{', '.join(map(str, anomaly_indices[:20]))}"
                    if len(anomaly_indices) > 20:
                        anomaly_text += f" 等共{len(anomaly_indices)}个"

                self.anomaly_info.setText(anomaly_text)  # Set initial text
                # self.ae_content_layout.addWidget(anomaly_info) # Removed separate widget

                
            except Exception as e:
                self._update_ae_status(f"显示RE²监控图失败: {str(e)}", 'error')
                import traceback
                traceback.print_exc()
                
        elif function == "spe":
            # 显示SPE监控图
            if not hasattr(self, 'ae_results') or not self.ae_results:
                self._update_ae_status("请先完成数据分析", 'warning')
                return
                
            try:
                # 设置统计量名称
                self.stat_name = "SPE"

                # 更新标题
                title_label = QLabel("SPE平方预测误差监控图表")
                title_label.setStyleSheet("""
                    font-size: 18px;
                    font-weight: bold;
                    color: #333;
                    margin-bottom: 15px;
                """)
                self.ae_content_layout.addWidget(title_label)
                
                # 创建图表
                fig = plt.figure(figsize=(12, 7))
                self.ax = fig.add_subplot(111)

                # 初始化动态绘制元素
                self.line, = self.ax.plot([], [], 'b-', linewidth=1, alpha=0.6, label='SPE')
                self.scatter = self.ax.scatter([], [], c='b', s=30, alpha=0.6)

                # 添加控制限
                control_limit = self.ae_results['spe_control_limit']
                self.ax.axhline(y=control_limit, color='r', linestyle='--',
                               label=f'控制限 ({control_limit:.3f})', linewidth=2)

                # 设置图表属性
                self.ax.set_title('SPE监控图表')
                self.ax.set_xlabel('样本编号')
                self.ax.set_ylabel('SPE')
                self.ax.legend()
                self.ax.grid(True, alpha=0.3)
                
                # 创建画布
                self.canvas = FigureCanvas(fig)
                self.canvas.setMinimumHeight(350)  # Further reduced minimum height
                self.canvas.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) # Allow vertical expansion

                # 创建图表容器
                chart_container = QWidget()
                chart_layout = QVBoxLayout(chart_container)
                chart_layout.addWidget(self.canvas)
                
                # 添加到界面
                self.ae_content_layout.addWidget(chart_container)
                
                # 设置基本变量
                self.stat_name = "SPE"  # 设置统计量名称
                control_limit = self.ae_results['spe_control_limit']
                anomalies = self.ae_results['spe_anomalies']
                anomaly_count = anomalies['count']
                anomaly_indices = np.where(anomalies['mask'])[0]

                # 准备实时更新数据
                self.monitoring_data = self.ae_results['spe_test']
                self.anomalies = self.ae_results['spe_anomalies']['mask']
                self.current_index = 0

                # 添加实时统计信息文本框
                self.anomaly_info = QTextEdit()
                self.anomaly_info.setMinimumHeight(100)  # Further reduced minimum height
                self.anomaly_info.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) # Allow expansion, but prefer fixed
                self.anomaly_info.setReadOnly(True)
                self.anomaly_info.setStyleSheet("""
                    QTextEdit {
                        font-family: 'Microsoft YaHei', sans-serif;
                        font-size: 14px;
                        line-height: 1.5;
                        padding: 10px;
                        background-color: #f8f9fa;
                        border: 1px solid #e9ecef;
                        border-radius: 4px;
                    }
                """)
                self.ae_content_layout.addWidget(self.anomaly_info)

                # 启动定时器
                if not hasattr(self, 'ae_timer'):
                    self.ae_timer = QTimer()
                    self.ae_timer.timeout.connect(self._update_ae_chart)
                self.ae_timer.start(50)

                # 添加异常统计信息 (Combined with real-time stats)
                anomaly_text = f"{self.stat_name}统计量分析结果：\n"
                anomaly_text += f"• 控制限：{control_limit:.4f}\n"
                anomaly_text += f"• 检测到的异常样本数：{anomaly_count}\n"

                if anomaly_count > 0:
                    anomaly_text += f"• 异常数据索引：{', '.join(map(str, anomaly_indices[:20]))}"
                    if len(anomaly_indices) > 20:
                        anomaly_text += f" 等共{len(anomaly_indices)}个"

                self.anomaly_info.setText(anomaly_text) # Set initial text
                # self.ae_content_layout.addWidget(anomaly_info) # Removed separate widget
                
            except Exception as e:
                self._update_ae_status(f"显示SPE监控图失败: {str(e)}", 'error')
                import traceback
                traceback.print_exc()
                
    def _update_ae_chart(self):
        """更新AE监控图表"""
        if not hasattr(self, 'monitoring_data') or self.current_index >= len(self.monitoring_data):
            if hasattr(self, 'ae_timer'):
                self.ae_timer.stop()
            return
            
        try:
            # 获取当前点
            x = self.current_index
            y = self.monitoring_data[x]
            
            # 更新线条数据
            current_x = list(self.line.get_xdata()) + [x]
            current_y = list(self.line.get_ydata()) + [y]
            self.line.set_data(current_x, current_y)
            
            # 更新散点数据
            offsets = np.array([current_x, current_y]).T
            self.scatter.set_offsets(offsets)
            
            # 如果是异常点，添加红色标记
            if self.anomalies[x]:
                self.ax.plot(x, y, 'rx', markersize=8, zorder=3)
            
            # 更新坐标范围
            self.ax.relim()
            self.ax.autoscale_view()
            
            # 更新画布
            self.canvas.draw()
            
            # 更新统计信息
            current_anomalies = self.anomalies[:self.current_index+1]
            anomaly_count = np.sum(current_anomalies)
            anomaly_indices = np.where(current_anomalies)[0]
            
            info_text = "实时统计信息：\n"
            info_text += f"• 已显示样本数：{self.current_index + 1}\n"
            info_text += f"• 当前检测到的异常数：{anomaly_count}\n"
            
            if anomaly_count > 0:
                recent_anomalies = anomaly_indices[-5:] if len(anomaly_indices) > 5 else anomaly_indices
                info_text += f"• 最近的异常样本索引：{', '.join(map(str, recent_anomalies))}"
                if len(anomaly_indices) > 5:
                    info_text += f" 等共{len(anomaly_indices)}个"
            
            self.anomaly_info.setText(info_text)
            
            # 更新索引
            self.current_index += 1
            
        except Exception as e:
            if hasattr(self, 'ae_timer'):
                self.ae_timer.stop()
            print(f"更新图表时出错: {str(e)}")
            import traceback
            traceback.print_exc()

    def _create_pca_panel(self):
        """创建PCA功能面板"""
        panel = QWidget()
        layout = QVBoxLayout(panel)
        layout.setContentsMargins(15, 20, 15, 15)
        layout.setSpacing(20)
        
        title = QLabel("PCA分析")
        title.setStyleSheet("""
            font-size: 22px;
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        self.btn_pca_analyze = FunctionButton("执行分析")
        self.btn_show_charts = FunctionButton("显示监控图")
        self.btn_show_variance = FunctionButton("方差解释图")
        self.btn_show_projections = FunctionButton("投影散点图")
        
        self.btn_pca_analyze.clicked.connect(lambda: self.show_pca_function("analyze"))
        self.btn_show_charts.clicked.connect(lambda: self.show_pca_function("monitoring"))
        self.btn_show_variance.clicked.connect(lambda: self.show_pca_function("variance"))
        self.btn_show_projections.clicked.connect(lambda: self.show_pca_function("projections"))
        
        self.pca_buttons = {
            "analyze": self.btn_pca_analyze,
            "monitoring": self.btn_show_charts,
            "variance": self.btn_show_variance,
            "projections": self.btn_show_projections
        }
        
        layout.addWidget(self.btn_pca_analyze)
        layout.addWidget(self.btn_show_variance)
        layout.addWidget(self.btn_show_projections)
        layout.addWidget(self.btn_show_charts)
        
        description = QLabel("请选择PCA分析的操作步骤")
        description.setStyleSheet("color: #888888; font-size: 14px; margin-top: 15px;")
        description.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(description)
        
        layout.addStretch()
        return panel

    def _ensure_pca_widget_created(self):
        """确保PCA部件已创建并显示在右侧区域"""
        # 确保停止自动翻页定时器
        if hasattr(self, 'viz_timer') and self.viz_timer.isActive():
            self.viz_timer.stop()
            print("切换到PCA: 停止自动翻页定时器")
            self.auto_flip_enabled = False
            if hasattr(self, 'auto_flip_btn'):
                self.auto_flip_btn.setChecked(False)
        
        if not hasattr(self, 'pca_widget') or self.pca_widget is None:
            try:
                from Mode.Pca import PCAWidget
                self.pca_widget = PCAWidget(self)
                
                # 如果已经加载了数据，传递给PCA界面
                if hasattr(self, 'data_df') and self.data_df is not None:
                    self.pca_widget.analyzer.data_df = self.data_df
                    self.pca_widget.analyzer.file_path = self.file_path
                    
                    # 传递日期和车间信息
                    if hasattr(self, 'selected_date'):
                        self.pca_widget.selected_date = self.selected_date
                    if hasattr(self, 'selected_workshop'):
                        self.pca_widget.selected_workshop = self.selected_workshop
                
                # 添加到内容显示区域
                if not hasattr(self, 'pca_content_index'):
                    self.pca_content_index = self.content_display.addWidget(self.pca_widget)
                
                # 显示PCA内容
                self.content_display.setCurrentIndex(self.pca_content_index)
                
                # 确保滚动条在顶部
                if hasattr(self.pca_widget, 'scroll_area'):
                    self.pca_widget.scroll_area.verticalScrollBar().setValue(0)
                    
                # 确保初始欢迎界面显示
                # 这里不需要额外操作，因为PCAWidget的init_ui方法已经创建了欢迎界面
                # 只需确保不清除它
            except Exception as e:
                print(f"创建PCA部件失败: {str(e)}")
                QMessageBox.critical(
                    self,
                    "错误",
                    f"加载PCA模块时出错: {str(e)}\n请确保已安装所需的Python库。"
                )
        else:
            # 如果已经存在PCA部件，直接显示并重置到欢迎页
            self.content_display.setCurrentIndex(self.pca_content_index)
            # 重置到欢迎页
            self.pca_widget.reset_to_welcome()
            
            # 确保滚动条在顶部
            if hasattr(self.pca_widget, 'scroll_area'):
                self.pca_widget.scroll_area.verticalScrollBar().setValue(0)

    def _update_ae_status(self, message, type='info'):
        """更新AE状态信息"""
        if hasattr(self, 'ae_status_label'):
            color = {
                'info': '#333333',  # 深灰色
                'success': '#52c41a',  # 绿色
                'warning': '#faad14',  # 黄色
                'error': '#f5222d'   # 红色
            }.get(type, '#333333')
            
            self.ae_status_label.setStyleSheet(f"""
                color: {color};
                font-size: 16px;
                padding: 10px;
            """)
            self.ae_status_label.setText(message)
            # 保持状态标签隐藏
            self.ae_status_label.setVisible(False)
    
    def _update_ae_progress(self, message):
        """更新AE进度信息"""
        if hasattr(self, 'ae_progress_text'):
            # 所有文本使用黑色
            color = '#000000'
            
            # 去除可能的特殊符号
            if message.endswith('...'):
                message = message[:-3]
            
            # 添加文本
            self.ae_progress_text.append(message)
            
            # 滚动到底部
            self.ae_progress_text.verticalScrollBar().setValue(
                self.ae_progress_text.verticalScrollBar().maximum()
            )
            QApplication.processEvents()
    
    def _clear_ae_content(self):
        """清除AE内容区域"""
        if hasattr(self, 'ae_content_layout'):
            # 保留标题、状态标签、进度区域、训练损失曲线图和欢迎页面，移除其它组件
            for i in reversed(range(self.ae_content_layout.count())):
                item = self.ae_content_layout.itemAt(i)
                if item.widget() not in [self.ae_header, self.ae_status_label, self.ae_progress_text, self.ae_canvas, getattr(self, 'ae_welcome_widget', None)]:
                    widget = item.widget()
                    if widget is not None:
                        widget.setParent(None)
                        widget.deleteLater()
            
            # 重置进度区域
            self.ae_progress_text.setVisible(False)
            
            # 处理欢迎页面的显示/隐藏
            if hasattr(self, 'ae_welcome_widget'):
                # 仅在执行功能操作时隐藏欢迎页面
                if hasattr(self, 'ae_buttons') and any(btn.isChecked() for btn in self.ae_buttons.values()):
                    self.ae_welcome_widget.setVisible(False)
                else:
                    # 如果没有选中任何功能按钮，显示欢迎页面
                    self.ae_welcome_widget.setVisible(True)
    
    def _show_ae_summary(self):
        """显示AE分析结果摘要"""
        if not hasattr(self, 'ae_results') or not self.ae_results:
            self._update_ae_status("无可用分析结果", 'warning')
            return
            
        # 清除之前的内容，保留标题和状态
        self._clear_ae_content()
        
        # 添加摘要标题
        summary_title = QLabel("分析结果摘要")
        summary_title.setStyleSheet("""
            font-size: 18px;
            font-weight: bold;
            color: #333;
            margin-bottom: 10px;
        """)
        self.ae_content_layout.addWidget(summary_title)
        
        # 创建按钮布局
        button_layout = QHBoxLayout()
        
        # 将按钮布局添加到主布局
        self.ae_content_layout.addLayout(button_layout)
        
        # 创建摘要文本区域
        summary_text = QTextEdit()
        summary_text.setReadOnly(True)
        summary_text.setStyleSheet("""
            QTextEdit {
                font-family: 'Microsoft YaHei', sans-serif;
                font-size: 14px;
                line-height: 1.6;
                padding: 15px;
                background-color: #f8f9fa;
                border: 1px solid #e9ecef;
                border-radius: 4px;
            }
        """)
        
        # 获取异常检测结果
        re2_anomalies = self.ae_results.get('re2_anomalies', {})
        spe_anomalies = self.ae_results.get('spe_anomalies', {})
        
        # 构建摘要HTML
        summary_html = f"""
        <h2 style='color: #1890ff;'>分析结果摘要</h2>
        <p><b>RE²检测结果:</b> 检测到 {re2_anomalies.get('count', 0)} 个异常样本 (占比 {re2_anomalies.get('percentage', 0):.2f}%)</p>
        <p><b>SPE检测结果:</b> 检测到 {spe_anomalies.get('count', 0)} 个异常样本 (占比 {spe_anomalies.get('percentage', 0):.2f}%)</p>
        <p><b>模型信息:</b> 自动编码器已成功训练，可用于故障检测</p>
        <p><b>建议:</b> 查看监控图表以获取更详细的分析结果</p>
        """
        
        summary_text.setHtml(summary_html)
        self.ae_content_layout.addWidget(summary_text)
        
        # 隐藏训练损失曲线图
        if hasattr(self, 'ae_canvas'):
            self.ae_canvas.setVisible(False)
            
        # 更新状态
        self._update_ae_status("分析完成！请选择要查看的图表", 'success')

    def _show_ae_loss_curve(self):
        """显示AE训练损失曲线"""
        # 清除之前的内容，保留标题和状态
        self._clear_ae_content()
        
        # 添加标题
        title = QLabel("训练损失曲线")
        title.setStyleSheet("""
            font-size: 18px;
            font-weight: bold;
            color: #333;
            margin-bottom: 10px;
        """)
        self.ae_content_layout.addWidget(title)
        
        # 显示训练损失曲线图
        if hasattr(self, 'ae_canvas'):
            self.ae_canvas.setVisible(True)
            
            # 如果有训练损失数据，重新绘制曲线
            if hasattr(self, 'ae_train_losses') and self.ae_train_losses:
                self.ae_ax.clear()
                epochs = range(1, len(self.ae_train_losses) + 1)
                self.ae_ax.plot(epochs, self.ae_train_losses, 'b-', linewidth=2, label='训练损失')
                
                # 设置图表属性
                self.ae_ax.set_title('自动编码器训练损失曲线', fontsize=16, fontweight='bold')
                self.ae_ax.set_xlabel('训练轮次', fontsize=14)
                self.ae_ax.set_ylabel('损失值', fontsize=14)
                self.ae_ax.grid(True, linestyle='--', alpha=0.7)
                self.ae_ax.legend(loc='upper right', fontsize=12)
                
                # 添加注释
                min_loss = min(self.ae_train_losses)
                min_epoch = self.ae_train_losses.index(min_loss) + 1
                self.ae_ax.annotate(f'最小损失: {min_loss:.6f}',
                                  xy=(min_epoch, min_loss),
                                  xytext=(min_epoch + 5, min_loss + 0.1),
                                  arrowprops=dict(facecolor='black', shrink=0.05, width=1.5),
                                  fontsize=12)
                
                # 刷新画布
                self.ae_canvas.draw()
        
        # 添加返回按钮
        button_layout = QHBoxLayout()
        back_button = ModernButton("返回摘要")
        back_button.setFixedHeight(40)
        back_button.clicked.connect(self._show_ae_summary)
        button_layout.addWidget(back_button)
        self.ae_content_layout.addLayout(button_layout)
        
        # 更新状态
        self._update_ae_status("查看训练损失曲线", 'info')

    def show_pca_function(self, function):
        """显示PCA特定功能"""
        if self.current_method != "PCA":
            self.change_method("PCA")
            # 在change_method中已经调用了_ensure_pca_widget_created，
            # 它会重置到欢迎页，所以这里不需要再次调用
        else:
            # 如果已经在PCA方法中，确保PCA部件已创建，但不重置到欢迎页
            if not hasattr(self, 'pca_widget') or self.pca_widget is None:
                self._ensure_pca_widget_created()
            else:
                # 确保显示PCA内容
                self.content_display.setCurrentIndex(self.pca_content_index)
                
                # 确保滚动条在顶部
                if hasattr(self.pca_widget, 'scroll_area'):
                    self.pca_widget.scroll_area.verticalScrollBar().setValue(0)
            
        for btn in self.pca_buttons.values():
            btn.setChecked(False)
        self.pca_buttons[function].setChecked(True)
        
        if function == "analyze":
            if not hasattr(self, 'file_path') or not self.file_path:
                self.pca_widget.update_status("请先加载数据文件", '#f5222d')
                return
                
            self.pca_widget.update_status("正在分析数据...", '#1890ff')
            QApplication.processEvents()
            
            success = self.pca_widget.analyzer.run_analysis(self.file_path)
            if success:
                # 分析成功后显示结果，但保留欢迎界面
                self.pca_widget.show_analysis_results()
                
                # 确保滚动条在顶部
                if hasattr(self.pca_widget, 'scroll_area'):
                    self.pca_widget.scroll_area.verticalScrollBar().setValue(0)
            else:
                self.pca_widget.update_status("分析失败", '#f5222d')
                
        elif function == "monitoring":
            if not self.pca_widget.analyzer.results:
                self.pca_widget.update_status("请先执行分析", '#faad14')
                return
            self.pca_widget.show_monitoring_charts()
            
            # 确保滚动条在顶部
            if hasattr(self.pca_widget, 'scroll_area'):
                self.pca_widget.scroll_area.verticalScrollBar().setValue(0)
            
        elif function == "variance":
            if not self.pca_widget.analyzer.results:
                self.pca_widget.update_status("请先执行分析", '#faad14')
                return
            self.pca_widget.show_variance_chart()
            
            # 确保滚动条在顶部
            if hasattr(self.pca_widget, 'scroll_area'):
                self.pca_widget.scroll_area.verticalScrollBar().setValue(0)
            
        elif function == "projections":
            if not self.pca_widget.analyzer.results:
                self.pca_widget.update_status("请先执行分析", '#faad14')
                return
            self.pca_widget.show_projections()
            
            # 确保滚动条在顶部
            if hasattr(self.pca_widget, 'scroll_area'):
                self.pca_widget.scroll_area.verticalScrollBar().setValue(0)

    def _ensure_dl_widget_created(self):
        """确保DL部件已创建并显示在右侧区域"""
        if not hasattr(self, 'dl_widget') or not self.dl_widget:
            try:
                from Mode.dl import DLWidget
                self.dl_widget = DLWidget(main_window=self)
                
                # 如果已经加载了数据，传递给DL界面
                if hasattr(self, 'data_df') and self.data_df is not None:
                    self.dl_widget.data_df = self.data_df
                    self.dl_widget.file_path = self.file_path
                
                # 添加到内容显示区域
                if not hasattr(self, 'dl_content_index'):
                    self.dl_content_index = self.content_display.addWidget(self.dl_widget)
                
                # 显示DL内容
                self.content_display.setCurrentIndex(self.dl_content_index)
            except Exception as e:
                print(f"创建DL部件失败: {str(e)}")
                QMessageBox.critical(
                    self,
                    "错误",
                    f"加载DL模块时出错: {str(e)}\n请确保已安装所需的Python库。"
                )
        else:
            # 如果已经存在DL部件，直接显示
            self.content_display.setCurrentIndex(self.dl_content_index)

    def _reset_ae_to_welcome(self):
        """重置AE界面到欢迎页状态"""
        if hasattr(self, 'ae_content_layout') and hasattr(self, 'ae_welcome_widget'):
            # 清除除欢迎页之外的所有内容
            self._clear_ae_content()
            
            # 确保欢迎页显示
            self.ae_welcome_widget.setVisible(True)
            
            # 确保进度区域隐藏
            if hasattr(self, 'ae_progress_text'):
                self.ae_progress_text.setVisible(False)
                
            # 确保训练损失曲线图隐藏
            if hasattr(self, 'ae_canvas'):
                self.ae_canvas.setVisible(False)
                
            # 确保标题和状态标签保持隐藏
            if hasattr(self, 'ae_header'):
                self.ae_header.setVisible(False)
                
            if hasattr(self, 'ae_status_label'):
                self.ae_status_label.setVisible(False)
            
            # 取消选中所有功能按钮
            if hasattr(self, 'ae_buttons'):
                for btn in self.ae_buttons.values():
                    btn.setChecked(False)

    def show_flow_chart(self):
        """显示流程图"""
        # 创建一个容器用于显示流程图
        flow_chart_container = QWidget()
        layout = QVBoxLayout(flow_chart_container)
        layout.setContentsMargins(15, 20, 15, 15)
        
        # 标题
        title = QLabel("流程")
        title.setStyleSheet("""
            font-size: 22px;
            font-weight: bold;
            color: #1890ff;
            margin-bottom: 15px;
        """)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 创建QLabel用于显示图片
        image_label = QLabel()
        image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 添加缩放功能说明
        info_label = QLabel("")
        info_label.setStyleSheet("color: #888888; font-size: 12px;")
        info_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 保存流程图路径作为容器的属性
        flow_chart_container.flow_chart_path = "data\流程图.png"
        
        # 定义一个缩放图片的函数，绑定到容器的resizeEvent
        def update_image_scale(event=None):
            pixmap = QPixmap(flow_chart_container.flow_chart_path)
            if not pixmap.isNull():
                # 获取当前容器的尺寸
                container_size = flow_chart_container.size()
                available_height = container_size.height() - 100  # 减去标题和边距的高度
                available_width = container_size.width() - 40    # 减去左右边距
                
                # 根据可用空间缩放图片，保持纵横比
                scaled_pixmap = pixmap.scaled(
                    available_width, 
                    available_height,
                    Qt.AspectRatioMode.KeepAspectRatio,
                    Qt.TransformationMode.SmoothTransformation
                )
                image_label.setPixmap(scaled_pixmap)
                
                # 显示缩放信息
                # info_label.setText(f"图片已缩放为 {scaled_pixmap.width()}x{scaled_pixmap.height()} 像素")
                # info_label.show()
            else:
                # 如果图片加载失败
                image_label.setText("无法加载流程图.png")
                info_label.hide()
        
        # 初次执行缩放
        update_image_scale()
        
        # 重写容器的resizeEvent方法
        flow_chart_container.resizeEvent = update_image_scale
        
        # 添加控件到布局
        layout.addWidget(image_label)
        layout.addWidget(info_label)
        
        # 存储或替换流程图索引
        if hasattr(self, 'flow_chart_index') and self.flow_chart_index is not None and self.flow_chart_index < self.content_display.count():
            # 已有流程图页面，替换它
            old_widget = self.content_display.widget(self.flow_chart_index)
            if old_widget:
                self.content_display.removeWidget(old_widget)
                old_widget.deleteLater()
            self.content_display.insertWidget(self.flow_chart_index, flow_chart_container)
        else:
            # 添加新的流程图页面
            self.content_display.addWidget(flow_chart_container)
            self.flow_chart_index = self.content_display.count() - 1
        
        # 显示流程图页面
        self.content_display.setCurrentIndex(self.flow_chart_index)
        
        # 高亮选中的按钮
        self.flow_chart_btn.setChecked(True)
        self.data_viz_btn.setChecked(False)
    
    def show_data_visualization(self):
        """显示数据可视化概览"""
        # 检查是否已加载数据
        if not hasattr(self, 'data_df') or self.data_df is None:
            QMessageBox.warning(
                self,
                "提示",
                "请先加载数据才能查看数据可视化"
            )
            return
        
        # 使用现有的数据可视化功能显示概览
        success = self.restore_data_visualization()
        
        # 如果没有现有的可视化，则创建一个
        if not success:
            self._create_data_visualization()
        
        # 初次显示时关闭自动翻页功能，用户可以手动开启
        if not hasattr(self, 'auto_flip_enabled_before'):
            # 标记为已经初始化过自动翻页状态
            self.auto_flip_enabled_before = True
            # 默认关闭自动翻页
            self.auto_flip_enabled = False
            if hasattr(self, 'auto_flip_btn'):
                self.auto_flip_btn.setChecked(False)
            
            # 确保定时器停止
            if hasattr(self, 'viz_timer') and self.viz_timer.isActive():
                self.viz_timer.stop()
                print("首次显示数据可视化: 默认关闭自动翻页")
        
        # 高亮选中的按钮
        self.flow_chart_btn.setChecked(False)
        self.data_viz_btn.setChecked(True)

    def auto_flip_viz_page(self):
        """自动翻页功能"""
        # 打印调试信息
        print(f"自动翻页触发: 当前页 {self.current_viz_page}, 总页数 {self.total_viz_pages if hasattr(self, 'total_viz_pages') else '未知'}")
        
        if hasattr(self, 'total_viz_pages') and self.total_viz_pages > 1:
            # 如果当前是最后一页，则回到第一页，否则前进到下一页
            if self.current_viz_page >= self.total_viz_pages - 1:
                self.current_viz_page = 0
            else:
                self.current_viz_page += 1
                
            plt.close('all')  # 关闭所有图表
            
            # 停止定时器，避免创建图表过程中触发定时器
            self.viz_timer.stop()
            
            # 创建新的数据可视化
            self._create_data_visualization()
            
            # 确保滚动区域回到顶部
            if hasattr(self, 'viz_scroll_area'):
                self.viz_scroll_area.verticalScrollBar().setValue(0)
            
            # 重新启动定时器
            if self.auto_flip_enabled:
                self.viz_timer.start(5000)
                print("已重启定时器")

    def toggle_auto_flip(self, checked):
        """切换自动翻页功能"""
        self.auto_flip_enabled = checked
        print(f"自动翻页设置为: {'启用' if checked else '禁用'}")
        
        if self.auto_flip_enabled:
            # 先确保定时器停止，避免重复启动
            if self.viz_timer.isActive():
                self.viz_timer.stop()
                print("停止之前的定时器")
            # 启动定时器，每5秒翻页一次
            self.viz_timer.start(5000)
            print("定时器已启动")
        else:
            # 停止定时器
            if self.viz_timer.isActive():
                self.viz_timer.stop()
                print("定时器已停止")

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建应用
    window = MainWindow()         # 创建主窗口
    window.show()                # 显示主窗口
    sys.exit(app.exec())        # 运行应用并退出